1

I'm fairly new to Ruby metaprogramming. I'm trying to write code which generates the "dup" function for a class when it's created, using a list of fields which should be passed into the constructor. However, I can't figure out how to get access to the name of the class I'm creating, while I'm creating it.

So for example, if I had this code:

class Example
  make_dup :name, :value
  attr_accessor :name, :value

  def initialize(name,value)
    @name, @value = name, value
  end
end

I'd want it to create the method:

def dup
  Example.new(name,value)
end

I'm just getting stuck on how it would figure out to insert Example there.

2
  • 3
    I don't understand what you mean by generating the dup method for the class, considering that it inherits Class#dup. As far as obtaining the class object, self equals Example as soon as class Example is parsed. You can verify that with a puts. Commented Nov 25, 2013 at 4:54
  • You've answered my questions. Thanks. Commented Nov 25, 2013 at 5:35

3 Answers 3

1

Note that all classes have built-in dup and clone methods. You can customize what happens in them by adding an initialize_copy method, e.g.:

class Foo
  attr_accessor :bar
  def initialize_copy(orig)
    super
    @bar = @bar.dup
  end
end

In case that isn't what you're truly looking for, you can access an object's class using its class method:

class Foo
  def p_class
    p self.class      # Foo.new.p_class => Foo     ; self is *a* `Foo'
  end

  def self.p_class
    p self.class      # Foo.p_class     => Class   ; self *is* `Foo'
  end
end
Sign up to request clarification or add additional context in comments.

1 Comment

not like you need the extra points but this is a really good answer
0
def dup
  self.class.new(name,value)
end

Comments

0

Maybe you can implement it this way:

module MyDup
  def make_dup(*args)
    define_method(:my_dup) do
      obj = self.class.new(nil, nil)
      args.each do |arg|
        obj.send(arg.to_s + "=", self.send(arg))
      end
      obj
    end
  end
end

class Example
  extend MyDup
  make_dup :name, :value
  attr_accessor :name, :value

  def initialize(name,value)
    @name, @value = name, value
  end
end

e = Example.new("John", 30)
p e

d = e.my_dup
p d

Execution result as follows:

#<Example:0x000000022325d8 @name="John", @value=30>
#<Example:0x00000002232358 @name="John", @value=30>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.