定义 Ruby 类方法的方式有区别吗?
给出以下两种在 Ruby 中定义类方法的方法:
class Foo
class << self
def bar
# ...
end
end
def self.baz
# ...
end
end
两者之间有区别吗? 一个比另一个更可取吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
简而言之:不,不。
这取决于个人喜好。 如果您定义了许多类方法,第一个版本可以节省您的打字时间。 如果您不喜欢第一个的模糊语法,则第二个可能更可取。
In short: no and no.
It comes down to personal preference. The first version saves you typing if you define many class methods. The second one may be preferable if you dislike the obscurer syntax of the first.
只是澄清一下术语:Ruby 中不存在“类方法”这样的东西。 您要做的就是在对象上定义一个单例方法,即
Foo
类(记住,类也是对象,就像任何其他)。 反过来,单例方法也不真正存在,它们只是对象的特征类(通常称为Foo'
)上的普通实例方法,其中这个例子也是Foo
类的元类。还困惑吗? :-)
没有区别
基本上,这样做:和这样做
:因为在类定义中,
self
绑定到类对象(在本例中为Foo
),这相当于:这又相当于:
正如您所看到的,这与我的第一个示例几乎完全相同。 这表明类方法上的单例方法和任何其他类型对象上的单例方法之间确实没有区别,因此在 Ruby 中谈论“类方法”是没有意义的。
您还可以看到这两个符号如何与单例方法和特征类的概念相关:
表示“将单例方法
baz
添加到对象foo
”和“打开特征类”对象
foo
的实例方法,然后将实例方法bar
添加到特征类中”。 但是,正如我们之前所建立的,对象的单例方法和对象的特征类的实例方法实际上是同一件事。 这就是为什么这两个符号表现不同是没有意义的。Just to clarify the terminology: there is no such thing as a "class method" in Ruby. What you are doing is to define a singleton method on the object that is the class
Foo
(remember, classes are objects, too, just like any other). In turn, singleton methods don't really exist, either, they are just normal instance methods on the eigenclass (commonly referred to asFoo′
) of the object, which in this case is also the metaclass of the classFoo
.Confused yet? :-)
Basically, there is no difference between doing this:
and this:
Because inside a class definition,
self
is bound to the class object (in this caseFoo
), that is equivalent to:Which is in turn equivalent to:
Which as you can see is pretty much exactly the same as my first example. This shows that there really is no difference between a singleton method on a class method and a singleton method on any other kind of object, therefore it doesn't make sense to talk about "class methods" in Ruby.
You can also see how these two notations relate to the notion of singleton methods and eigenclasses:
says "add the singleton method
baz
to the objectfoo
" and"open up the eigenclass of object
foo
and then add instance methodbar
to the eigenclass". But, as we established earlier, a singleton method of the object and an instance method of the object's eigenclass are really the same thing. That's why it wouldn't make sense for those two notations to behave differently.正如莫尔夫所说,没有任何有效的区别。 但在我看来,第二个更容易浏览——很容易错过
class< 并认为您仍在查看实例方法。 我只倾向于在需要更多动态行为时使用
class< 路由,例如为类本身创建
attr_accessor
属性。As molf said, there's no effective difference. But IMO, the second is so much more skimmable -- it's too easy to miss the
class<<self
and think you're still looking at instance methods. I only tend to use theclass<<self
route when I need more dynamic behavior, such as makingattr_accessor
properties of the class itself.如果您在
class << 之间有很多代码行,选项 1. 会给您带来麻烦。 self
和相应的end
。 如果您没有注意到类中已经定义了一个方法<< self
块,您可能认为它只是一个实例方法。选项 2. 对于未经训练的 Ruby-eye 来说,输入更多、更具表现力并且更容易理解。
正如其他人已经指出的那样,它们的最终结果没有区别。
Option 1. will get you into trouble if you've got a lots of lines of code between
class << self
and the correspondingend
. If you don't notic that a method has been defined inside theclass << self
block, you might think its just an instance method.Option 2. is more typing, more expressive and more understandable to the untrained Ruby-eye.
Theyre's no difference in the end-result as others have pointed already.