简单的问题,但我一直很好奇的是......以下两个命令之间存在功能差异吗?
String::class
String.class
他们都做我期望的事 - 也就是说他们返回Class
- 但使用::
和.
之间的区别是什么?
我注意到在那些定义了常量的类中,当你在::
之后而不是.
之后按Tab键时,IRB的自动完成将返回常量作为可用选项,但我不知道这是什么原因......
答案 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.HTTP
。 Net::HTTP
不正确,但{{1}}是。