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

时间:2022-01-26 00:20:19

Simple question, but one that I've been curious about...is there a functional difference between the following two commands?

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

String::class
String.class

They both do what I expect -- that is to say they return Class -- but what is the difference between using the :: and the .?

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

I notice that on those classes that have constants defined, IRB's auto-completion will return the constants as available options when you press tab after :: but not after ., but I don't know what the reason for this is...

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

2 个解决方案

#1


35  

The . operator basically says "send this message to the object". In your example it is calling that particular member. The :: operator "drills down" to the scope defined to the left of the operator, and then calls the member defined on the right side of operator.

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

When you use :: you have to be referencing members that are defined. When using . you are simply sending a message to the object. Because that message could be anything, auto-completion does not work for . while it does for ::.

使用::时必须引用已定义的成员。使用时。您只是向对象发送消息。因为该消息可以是任何内容,所以自动完成不起作用。虽然它适用于::。

#2


11  

Actually, auto-completion does work for .. The completion options are found by calling #methods on the object. You can see this for yourself by overriding Object.methods:

实际上,自动完成确实有效..通过在对象上调用#methods找到完成选项。您可以通过重写Object.methods来自行查看:

>> def Object.methods; ["foo", "bar"]; end
=> nil
>> Object.[TAB]
Object.foo  Object.bar
>> Object.

Note that this only works when the expression to the left of the . is a literal. Otherwise, getting the object to call #methods on would involve evaluating the left-hand side, which could have side-effects. You can see this for yourself as well:

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

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

We add a method #baz to Object which returns Object itself. Then we auto-complete to get the methods we can call on Object.baz. If IRB called Object.baz.methods, it would get the same thing as Object.methods. Instead, IRB has 1022 suggestions. I'm not sure where they come from, but it's clearly a generic list which isn't actually based on context.

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

The :: operator is (also) used for getting a module's constants, while . is not. That's why HTTP will show up in the completion for Net::, but not for Net.. Net.HTTP isn't correct, but Net::HTTP is.

::运算符(也)用于获取模块的常量,而。不是。这就是为什么HTTP将在Net ::的完成中出现,但不会出现在Net .. Net.HTTP不正确,但Net :: HTTP是。

#1


35  

The . operator basically says "send this message to the object". In your example it is calling that particular member. The :: operator "drills down" to the scope defined to the left of the operator, and then calls the member defined on the right side of operator.

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

When you use :: you have to be referencing members that are defined. When using . you are simply sending a message to the object. Because that message could be anything, auto-completion does not work for . while it does for ::.

使用::时必须引用已定义的成员。使用时。您只是向对象发送消息。因为该消息可以是任何内容,所以自动完成不起作用。虽然它适用于::。

#2


11  

Actually, auto-completion does work for .. The completion options are found by calling #methods on the object. You can see this for yourself by overriding Object.methods:

实际上,自动完成确实有效..通过在对象上调用#methods找到完成选项。您可以通过重写Object.methods来自行查看:

>> def Object.methods; ["foo", "bar"]; end
=> nil
>> Object.[TAB]
Object.foo  Object.bar
>> Object.

Note that this only works when the expression to the left of the . is a literal. Otherwise, getting the object to call #methods on would involve evaluating the left-hand side, which could have side-effects. You can see this for yourself as well:

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

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

We add a method #baz to Object which returns Object itself. Then we auto-complete to get the methods we can call on Object.baz. If IRB called Object.baz.methods, it would get the same thing as Object.methods. Instead, IRB has 1022 suggestions. I'm not sure where they come from, but it's clearly a generic list which isn't actually based on context.

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

The :: operator is (also) used for getting a module's constants, while . is not. That's why HTTP will show up in the completion for Net::, but not for Net.. Net.HTTP isn't correct, but Net::HTTP is.

::运算符(也)用于获取模块的常量,而。不是。这就是为什么HTTP将在Net ::的完成中出现,但不会出现在Net .. Net.HTTP不正确,但Net :: HTTP是。