Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby元编程:访问类名_Ruby_Metaprogramming - Fatal编程技术网

Ruby元编程:访问类名

Ruby元编程:访问类名,ruby,metaprogramming,Ruby,Metaprogramming,我对Ruby元编程相当陌生。我正在尝试编写生成 创建类时,使用应传递到构造函数中的字段列表为类执行“dup”函数。但是,在创建类的同时,我不知道如何访问我正在创建的类的名称 例如,如果我有以下代码: class Example make_dup :name, :value attr_accessor :name, :value def initialize(name,value) @name, @value = name, value end end 我希望它创建以下

我对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

我一直在想如何在那里插入
示例

也许您可以这样实现:

def dup
  self.class.new(name,value)
end
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>
#
#

也许您可以这样实现:

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>
#
#

请注意,所有类都有内置的
dup
clone
方法。您可以通过添加
initialize\u 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

请注意,所有类都有内置的
dup
clone
方法。您可以通过添加
initialize\u 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

我不明白您为类生成
dup
方法是什么意思,因为它继承了
class\dup
。就获取类对象而言,
self
等于
Example
,只要
class-Example
被解析。您可以使用
按钮验证这一点。您已经回答了我的问题。谢谢。我不明白你为类生成
dup
方法是什么意思,因为它继承了
class\dup
。就获取类对象而言,
self
等于
Example
,只要
class-Example
被解析。您可以使用
按钮验证这一点。您已经回答了我的问题。谢谢。你不需要加分,但这是一个非常好的答案。你不需要加分,但这是一个非常好的答案