【问题标题】:Ruby metaprogramming: accessing class nameRuby 元编程:访问类名
【发布时间】:2013-11-25 04:02:40
【问题描述】:

我对 Ruby 元编程还很陌生。我正在尝试编写生成的代码 创建类时的“dup”函数,使用应传递给构造函数的字段列表。但是,我不知道如何在创建时访问我正在创建的类的名称。

例如,如果我有这个代码:

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

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

我希望它创建方法:

def dup
  Example.new(name,value)
end

我只是想知道如何在其中插入Example

【问题讨论】:

  • 我不明白你为类生成dup 方法是什么意思,考虑到它继承Class#dup。就获取类对象而言,只要解析了class Exampleself 就等于Example。您可以使用puts 进行验证。
  • 你已经回答了我的问题。谢谢。

标签: ruby metaprogramming


【解决方案1】:

请注意,所有类都有内置的dupclone 方法。您可以通过添加initialize_copy 方法来自定义其中发生的情况,例如:

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

如果这不是您真正想要的,您可以使用对象的类方法访问对象的类:

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

【讨论】:

  • 不像你需要加分,但这是一个非常好的答案
【解决方案2】:
def dup
  self.class.new(name,value)
end

【讨论】:

    【解决方案3】:

    也许你可以这样实现:

    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
    

    执行结果如下:

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

    【讨论】:

      猜你喜欢
      • 2010-09-16
      • 1970-01-01
      • 1970-01-01
      • 2010-09-08
      • 1970-01-01
      • 1970-01-01
      • 2011-10-08
      • 1970-01-01
      • 2011-04-22
      相关资源
      最近更新 更多