Ruby动态实例化类

时间:2013-04-03 12:16:22

标签: ruby

如何在静态方法中引用类?

class Car
  def self.new_from_xml(xml)
    instance = self.class.new
    #do some stuff with xml
    instance
  end
end

class Mercedes < Car
end

class Porsche < Car
end

IRB:

Mercedes.new_from_xml(somedata) # Output is #<Class:...>, should be #<Mercedes:...>
Porsche.new_from_xml(somedata)  # Output is #<Class:...>, should be #<Porsche:...>

2 个答案:

答案 0 :(得分:4)

而不是

instance=self.class.new

写一下

instance = new

为什么会这样?

嗯,首先,您必须了解您正在调用类方法,因此您已经处于类级别。 .new方法是一个类方法,因此您可以直接调用它而无需调用self.class.new。

为什么self.class.new会返回Class?

因为类Car的类是Class(我知道,听起来很奇怪;),因为Ruby中的类是Class的实例。

这实际上是一个非常深刻的概念,我建议你阅读更多关于它的内容。我读过的一个很好的参考是Paolo Perrotta的Metaprogramming Ruby(ISBN-10:1934356476)[1]。

  1. http://www.amazon.com/Metaprogramming-Ruby-Program-Like-Pros/dp/1934356476

答案 1 :(得分:2)

由于您已经使用了类方法,因此应使用self.new(或简称为new,而不是self.class.new代替class Car def self.new_from_xml(xml) instance = new #do some stuff with xml end end class Mercedes < Car end class Porsche < Car end p Mercedes.new_from_xml(nil) #=> #<Mercedes:0x007f042d0db208> p Porsche.new_from_xml(nil) #=> #<Porsche:0x007f042d0db118>

self

从评论到这个答案:为什么self.class引用了类?这里的逻辑是什么?

在类块class Car puts self #=> writes Car end 内引用您正在编辑的类:

def self.new_from_xml

使用def Car.new_from_xml就像是在声明Car,这是Class对象的方法(new_from_xml的一个实例);所以self Car内部与{{1}}重合。