3

If all 'functions' in Ruby are methods, so when I call methods without explicitly mentioning the object they are invoked on, who are they sent to?

The Ruby Programming Language book (Flanagan & Matsumoto) says if the object is omitted the method is invoked on self.

So if this code works

p "123"

Then this should work

self.p "123"

but it doesnt!

In this case I ran this in global scope so self is main and self.class is Object. So I can't invoke p on a simple Object instance (which makes sense).

I understand that Object includes Kernel where p is declared. How does the interpreter know how to access this declaration?

yonso
  • 275
  • 2
  • 12
  • 1
    The method is private. See http://stackoverflow.com/questions/4293215/understanding-private-methods-in-ruby – rainkinz Mar 18 '13 at 19:22
  • 1
    Did you actually read the error message? It explains quite clearly what is going on. – Jörg W Mittag Mar 18 '13 at 19:42
  • It's hard to guess from NoMethodError that it is the same object being invoked and that the method is private. Also Ruby's approach to private methods is not trivial for a Ruby beginner, especially after experience with Java, C++ etc – yonso Mar 18 '13 at 21:15
  • Oh sorry you are right, it does actually say private method called. I am using Netbeans and yes I didn't even read the whole line. Stupid :( – yonso Mar 18 '13 at 21:24

2 Answers2

4

For runtime Ruby has special object the main.

It's some kind of trick that all code runs in the context of this object.

So when you're typing methods like puts, p and so on, all of them are calling in the context of self object and passing to self object.

And here's the second thing - the access control. As you probably know, Ruby has keywords like private, protected and public - all of them manage the access of calling methods on object. Ruby is checking this access control only when you're have construction like

<name_of_object>.your_method and self.your_method

So when you're typing

self.p "something"

Ruby will decline this call because the p method is private method.

megas
  • 21,401
  • 12
  • 79
  • 130
  • Thank you, your answer led me to fully understanding this issue. I posted an explicit example – yonso Mar 18 '13 at 20:07
0

It is simply an access issue as the user megas explained. This example shows it explicitly-

class Object

  def checking
    p self
  end

  private

  def private_checking
    p self
  end

end


checking                  #=>main
self.checking             #=>main

private_checking          #=>main
self.private_checking     #=>NoMethodError
yonso
  • 275
  • 2
  • 12