Ruby: Overriding Class.new to make custom wrapper pattern

If you have a class Content and you call Content.new, you’ll get back an object of class Content. This is normal and expected. If you want something that is abnormal and unexpected to occur, this recipe is for you. While here we just implement a simple wrapper pattern, you could just as easily have Content.new return objects of class DefinitelyNotContent or BombsIfTheProgrammerTriesToUseThisAsContent.


class Wrapper
  attr_accessor :content

  def initialize(content)
    @content = content
  end

  def content_value
    @content.value
  end
end

class Content
  attr_accessor :value

  class << self
    alias_method :new_orig, :new

    def new(*args)
      o = new_orig *args
      Wrapper.new(o)
    end
  end

  def initialize(default)
    @value = default
  end

end

class ComplicatedContent < Content
  alias_method :simple_value, :value
  def value
    simple_value.reverse
  end
end

c = Content.new("a_to_z")
puts "Content.new("test"):"
puts "- class = #{c.class}"
puts "- value = #{c.content_value}"

c = ComplicatedContent.new("a_to_z")
puts "ComplicatedContent.new("test"):"
puts "- class = #{c.class}"
puts "- value = #{c.content_value}"
Tagged , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

One Comment

  1. Posted February 12, 2009 at 8:53 am | Permalink

    This code can be simplified a bit and can also be made more reusable.

    http://gist.github.com/62556

    in the singleton_super_version.rb file, you can see that you can use super when in the singleton class to access methods in the superclass.

    in the module_inclusion.rb file, you’ll see that the method you present is a shortcut when you don’t want your behavior to be resused, I think it’s better to have a separate module for this type of thing.

    Good post!

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>