Hi --

On Fri, 13 Aug 2010, David Waller wrote:

> 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!!

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