Ruby is pretty consistent about classes and objects. However, when it comes to top-level method declaration, that rule somehow breaks down. For example,
$ puts self # => main
$ puts self.class # => Object
However, the methods declared in the context of this main object are somehow available as private methods of class Object.
Is there any logical explanation for this? I understand that this is very convenient as these methods appear as “stand-alone functions”, but taking it just as “it just is so” breaks the otherwise consistent rules, as normally you have to define a method in the context of a class for it to be a method of that class. However, the main object is not class Object, nor is it a class at all.
Re-framing my question:
In what scope does the method gets declared inside ruby’s REPL? {class Object/ object main or module Kernel}
Regarding private nature of methods declared in REPL, plz see the following example:
def my_method # "a method declared in REPL"
puts "method called"
end
# calling my_method in REPL aka top-level scope
my_method # => "method called"
[].my_method # => private method `my_method' called for []:Array (NoMethodError)
Array.my_method # => private method `my_method' called for Array:Class (NoMethodError)
Q: If my_method is defined as a private method under class Object, then why is self set to main instead of class Object. If someone says that its not under private scope, then why am I getting above mentioned error?
Although I’m not sure I fully understand the question, I’ll try to answer:
When you’re working inside
irbyou’re really working in a context like this:So, if you declare a method inside the REPL you’re actually declaring it inside
main‘s class:I’m not sure where you get the idea that the methods defined there are private to the class (but again, I might be misunderstanding the question).
The class you’re inside in
irbincludes theKernelmodule so that’s why you have access to its functions (which, since you’re inside the class, appear as stand-alone functions even though they’re regular methods):This would make it consistent with the typical Ruby behavior and indeed,
mainis justselfinside the Object class.If you call
selfyou’ll receivemainbecause that’s the way it’s instructed to do it through inspect. We can remove the#to_smethod fromselfand see the real value:Edit: Before moving forward I think you should clarify which Ruby version are you using, see the sample below for 1.9.3: