self in irb versus script

D

David Waller

Howdy from a Ruby newbie--hope my question isn't too annoying.

I'm working through a book on Ruby. Examples using self work fine in
irb, but if I type the same examples in a script and run that I get this
error message: private method called for...NoMethodError.

So, my question is: what do I need to type to properly invoke self in a
script (but that is not needed in the irb?).

I should mention that the explanation of public vs. private methods
isn't helping me. If I could just see what I have to actually type to
use self in a script vs. the irb a light would go off in my head.

Here's an example that runs in irb, but not in a script:


def add(n)
self + n
end


puts 2.add(2)


The irb will display the result 4, but the script gives the "private
method...NoMethodError" message.

I'm puzzled as to why Ullman does not address this in his section on
"Using Self."

Thanks!

-Doc Waller
 
I

Iain Barnett

Howdy from a Ruby newbie--hope my question isn't too annoying.
=20
I'm working through a book on Ruby. Examples using self work fine in
irb, but if I type the same examples in a script and run that I get = this
error message: private method called for...NoMethodError.
=20
So, my question is: what do I need to type to properly invoke self in = a
script (but that is not needed in the irb?).
=20
I should mention that the explanation of public vs. private methods
isn't helping me. If I could just see what I have to actually type to
use self in a script vs. the irb a light would go off in my head.
=20
Here's an example that runs in irb, but not in a script:
=20
=20
def add(n)
self + n
end
=20
=20
puts 2.add(2)
=20
=20
The irb will display the result 4, but the script gives the "private
method...NoMethodError" message.
=20
I'm puzzled as to why Ullman does not address this in his section on
"Using Self."
=20
Thanks!
=20
-Doc Waller
--=20
Posted via http://www.ruby-forum.com/.

My irb gave me an error until I added the definition to a class (Integer =
seemed right) :

$ irb =20
NoMethodError: undefined method `add' for 2:Fixnum
from (irb):1
from /Library/Frameworks/Ruby.framework/Programs/irb:12:in =
` said:
def add(n)
self + n
end
=3D> nil
NoMethodError: private method `add' called for 2:Fixnum
from (irb):5
from /Library/Frameworks/Ruby.framework/Programs/irb:12:in =
` said:
class Integer
def add(n)
self + n
end
end
=3D> nil
=3D> 4

I'm not sure why your irb didn't give an error. Did you load any files =
into it?


Iain
 
D

David Waller

Iain Barnett wrote:

I'm not sure why your irb didn't give an error. Did you load any files
into it?


Iain

Thanks, Iain. no, I didn't load any files (that I'm aware of)--and I
double-checked just now by opening up the terminal fresh and going
straight to irb and typing it in again--no error.

However, I did find that putting the method into the Integer class as
you did made the method work properly in a saved script! That moves my
understanding of self forward a bit. Many thanks for your kind
response!!

-Dave
 
D

David A. Black

Hi --

Iain Barnett wrote:



Thanks, Iain. no, I didn't load any files (that I'm aware of)--and I
double-checked just now by opening up the terminal fresh and going
straight to irb and typing it in again--no error.

However, I did find that putting the method into the Integer class as
you did made the method work properly in a saved script! That moves my
understanding of self forward a bit. Many thanks for your kind
response!!

The difference you're seeing is a difference in the way irb and the
non-irb interpreter handle top-level methods. If you define a top-level
method in a regular Ruby script, it becomes a private instance method of
Object:

$ ruby -e 'def x; end; p Object.private_instance_methods(false)'
["initialize", "x"]

In irb, such methods become public instance methods of Object:

irb(main):002:0> def x; end; p Object.public_instance_methods(false)
["x"]

Private instance methods of Object are known to all objects, but because
they're private, they can only be called without an explicit receiver.
That means that you can't do:

def x; end
some_object.x # error: private method

It's the same with methods like puts, raise, exit, and sleep. You can
call:

sleep(3)

but not:

some_object.sleep(3)

(puts and company are actually private instance methods of Kernel, but
it's the same kind of effect.)

The point of all this is to allow Ruby to have these top-level methods,
while still adhering underneath to the principle that every method call
is a message being sent to some object.


David

--
David A. Black, Senior Developer, Cyrus Innovation Inc.

The Ruby training with Black/Brown/McAnally
Compleat Philadelphia, PA, October 1-2, 2010
Rubyist http://www.compleatrubyist.com
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top