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

时间:2008-09-04 03:21:31

标签: ruby syntax

简单的问题,但我一直很好奇的是......以下两个命令之间存在功能差异吗?

String::class
String.class

他们都做我期望的事 - 也就是说他们返回Class - 但使用::.之间的区别是什么?

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

2 个答案:

答案 0 :(得分:35)

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

当您使用::时,您必须引用已定义的成员。使用.时,您只是向对象发送消息。由于该消息可以是任何内容,因此自动完成功能对.的{​​{1}}不起作用。

答案 1 :(得分:11)

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

来自行查看
>> def Object.methods; ["foo", "bar"]; end
=> nil
>> Object.[TAB]
Object.foo  Object.bar
>> Object.

请注意,这只适用于.左侧的表达式是文字的情况。否则,让对象调用#methods将涉及评估左侧,这可能有副作用。您也可以自己看到这个:

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

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

::运算符(也)用于获取模块的常量,而.则不是。HTTP运算符用于获取模块的常量。这就是Net::完成Net.时出现的原因,而不是Net.HTTPNet::HTTP不正确,但{{1}}是。