Is there a difference between :: and . when calling class methods in Ruby?
Simple question, but one that I've been curious about...is there a functional difference between the following two commands?
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...
. 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
>> 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
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.
:: 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.HTTP isn't correct, but