关于语法:::和之间有区别吗? 在Ruby中调用类方法时?

关于语法:::和之间有区别吗? 在Ruby中调用类方法时?

Is there a difference between :: and . when calling class methods in Ruby?

这是一个简单的问题,但是我一直很好奇...下面两个命令之间在功能上有区别吗?

1
2
String::class
String.class

它们都符合我的期望-也就是说它们返回Class-但是使用::.有什么区别?

我注意到在那些定义了常量的类上,当您在::之后而不是在.之后按tab时,IRB的自动完成功能会将常量作为可用选项返回,但是我不知道这是什么原因。 ..


.运算符基本上说"将该消息发送给对象"。在您的示例中,它正在呼叫该特定成员。 ::运算符"向下钻取"到在运算符左侧定义的范围,然后调用在运算符右侧定义的成员。

使用::时,必须引用已定义的成员。使用.时,您只是向对象发送一条消息。由于该消息可能是任何内容,因此自动完成功能不适用于.,而适用于::


实际上,自动完成功能确实适用于.。通过在对象上调用#methods可以找到完成选项。您可以通过覆盖Object.methods自己看到它:

1
2
3
4
5
>> def Object.methods; ["foo","bar"]; end
=> nil
>> Object.[TAB]
Object.foo  Object.bar
>> Object.

请注意,这仅在.左侧的表达式为文字时有效。否则,让对象调用#methods将涉及评估左侧,这可能会有副作用。您也可以自己查看:

1
2
3
4
5
[continuing from above...]
>> def Object.baz; Object; end
=> nil
>> Object.baz.[TAB]
Display all 1022 possibilities? (y or n)

我们向Object添加方法#baz,该方法本身返回Object。然后,我们自动完成以获取可以在Object.baz上调用的方法。如果IRB调用Object.baz.methods,它将得到与Object.methods相同的效果。相反,IRB有1022条建议。我不确定它们来自哪里,但是显然这是一个通用列表,实际上并不基于上下文。

::运算符(也)用于获取模块的常数,而.则不是。这就是HTTP将显示在Net::的补全中而不显示在Net.的原因中的原因。 Net.HTTP不正确,但Net::HTTP是正确的。


推荐阅读