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

时间:2020-03-05 18:47:26  来源:igfitidea点击:

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

String::class
String.class

它们都按照我的期望进行操作-也就是说它们将返回Class-但是使用::.有什么区别?

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

解决方案

回答

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

当使用::时,必须引用已定义的成员。使用.时,我们只是向对象发送一条消息。因为该消息可以是任何内容,所以自动补全不适用于.,而适用于:::`。

回答

实际上,自动补全确实适用于.。通过在对象上调用#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)

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

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