Buck Shlegeris
Buck Shlegeris

Reputation: 517

Ruby metaprogramming: accessing class name

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

Answers (3)

uncutstone
uncutstone

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

Denis de Bernardy
Denis de Bernardy

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

davogones
davogones

Reputation: 7399

def dup
  self.class.new(name,value)
end

Upvotes: 0

Related Questions