Reputation: 27862
I have read that "puts" is a private instance method of the module Kernel (and therefore of Object, since Object mixes in Kernel).
That's why when we call puts, we don't specify a explicit receiver. My question is, if it's a private instance method, how is it possible that we can call it from any other scope? So, we can do:
class Test
puts "hello" # self is Test. So, we are calling self.puts "hello" -
end
What am I missing here? How is it possible that this works? We are calling a private instance method?
EDIT:
Same question arises if I do this:
class Object
private
def talk
puts "hi there"
end
end
class Test
talk # outputs 'hi there'
end
Why is it possible that from class Test we can call a private method from the class Object?
Upvotes: 3
Views: 335
Reputation: 168269
I don't understand why such long answer as in the other answer is required, or is upvoted. The answer to your question is simple.
It is because almost all classes (i.e., anything other than BasicObject
) includes Kernel
. Therefore, in the scope of a usual object, Kernel
class is inherited, and hence its methods are accessible. That is all.
Upvotes: 0
Reputation: 3669
Please have a look at the doc for the Kernel module - http://www.ruby-doc.org/core-2.0.0/Kernel.html.
Unlike Java, Ruby is not limited to Classes as containers of implementations. Modules act as wonderful containers which can be mixed into other classes. When a module is mixed into another class, all its instance methods become instance methods of those class. Since the Kernel module is mixed into the Object class, its methods are therefore available in all Ruby classes.
Please read the following:
With the risk of duplication, I have to say this: private
in Ruby is not the same as in C++ or Java. Subclasses of a class can call private methods declared in their superclass. In fact, you can call private method of any class using :send
. The only difference between private and protected methods is that private methods can't be called with explicit receivers.
Even the last rule has an exception. If your private method is something like age=
, it can (and has to be) called with self
. Funny, isn't it? :)
UPDATE: (to explain the gist):
The talk
method which you wrote in your code above is being called on the main
object which is the context for all Ruby programs. It's not being called on the Test class which is why it's not working for your second gist.
In the gist that I have provided, talk
is a private class method which is why it gets executed at the time of class definition. In the same gist, the talk2
method is an instance method and can only be called from within instance methods. Your example gist didn't work because you were trying to invoke an instance method at the time of defining the class.
Upvotes: 3