给出以下两种在Ruby中定义类方法的方法:
class Foo
class << self
def bar
# ...
end
end
def self.baz
# ...
end
end
这两者有区别吗?比另一个更优选吗?
答案 0 :(得分:3)
简而言之:不,不。
归结为个人偏好。如果您定义了许多类方法,则第一个版本会保存您的输入。如果你不喜欢第一个的模糊语法,那么第二个可能更好。
答案 1 :(得分:3)
只是为了澄清术语:Ruby中没有“类方法”这样的东西。你正在做的是在对象上定义一个单例方法,它是类Foo
(记住,类也是对象,就像任何其他对象一样) 。反过来,单例方法也不存在,它们只是对象的本征类(通常称为Foo′
)的正常实例方法,在这种情况下也是类Foo
的元类。
困惑了吗? : - )
基本上,这样做没有区别:
foo = Object.new
class << foo
def bar
# ...
end
end
def foo.baz
# ...
end
和此:
class Foo
class << self
def bar
# ...
end
end
def self.baz
# ...
end
end
因为在类定义中,self
绑定到类对象(在本例中为Foo
),这相当于:
class Foo
class << Foo
def bar
# ...
end
end
def Foo.baz
# ...
end
end
这相当于:
Foo = Class.new
class << Foo
def bar
# ...
end
end
def Foo.baz
# ...
end
你可以看到的与我的第一个例子完全一样。这表明在类方法上的单例方法和在任何其他类型的对象上的单例方法之间确实没有区别,因此在Ruby中讨论“类方法”是没有意义的。
您还可以看到这两个符号如何与单例方法和特征类的概念相关:
def foo.baz
# ...
end
说“将单身方法baz
添加到对象foo
”和
class << foo
def bar
# ...
end
end
“打开对象foo
的本征类,然后将实例方法bar
添加到本征类”。但是,正如我们之前建立的那样,对象的单例方法和对象的本征类的实例方法实际上是相同的。这就是为什么这两种符号表现不同的原因是没有意义的。
答案 2 :(得分:0)
正如莫尔夫所说,没有有效的区别。但IMO,第二个是更易于浏览的 - 很容易错过class<<self
并认为你仍然在寻找实例方法。当我需要更多动态行为时,我倾向于使用class<<self
路由,例如创建类本身的attr_accessor
属性。
答案 3 :(得分:0)
选项1.如果您在class << self
和相应的end
之间有大量代码,则会遇到麻烦。如果您没有注意到class << self
块中已经定义了一个方法,您可能会认为它只是一个实例方法。
选项2.对未经训练的Ruby-eye进行更多打字,更具表现力和更易理解。
他们已经指出了最终结果没有区别。