Reputation: 517
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.
Upvotes: 1
Views: 356
Reputation: 408
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>
Upvotes: 0
Reputation: 78413
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
Upvotes: 1