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 .
?
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...
The use of :: on the class name means that it is an absolute, top-level class; it will use the top-level class even if there is also a TwelveDaysSong class defined in whatever the current module is.
In ruby, the concept of object orientation takes its roots from Smalltalk. Basically, when you call a method, you are sending that object a message. So, it makes sense that when you want to dynamically call a method on an object, the method you call is send . This method has existed in ruby since at least 1.8.
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 ::
.
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
:
>> 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:
[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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With