Interesting behaviour

When I does following thing on irb console

def foo
1
end

foo ===>o/p 1
foo.foo ===>o/p 1
foo.foo.foo ===>o/p 1
foo.foo.foo.foo.foo.foo.foo.foo.foo.foo.foo.foo.foo.foo.foo…foo
===>o/p 1

I got above o/p


But when I done same thing in Scite editor. I got error

def foo
1
end

p foo
p foo.foo =>o/p private method `foo’ called for 1:Fixnum
(NoMethodError)

How ??

thanks
DG

Deepak G. wrote:

def foo
1
end

foo ===>o/p 1
foo.foo ===>o/p 1
foo.foo.foo ===>o/p 1
foo.foo.foo.foo.foo.foo.foo.foo.foo.foo.foo.foo.foo.foo.foo…foo
===>o/p 1

I got above o/p

I see the same with ruby 1.8.6.

It looks like you have defined foo as a method in Object, and hence is
available to all objects:

def foo; 1; end
=> nil

“hello”.foo
=> 1

Object.instance_methods.grep(/foo/)
=> [“foo”]

Ruby 1.9 makes this slightly better by making the method private:

$ irb19 --simple-prompt

“hello”.foo
NoMethodError: undefined method foo' for "hello":String from (irb):1 from /usr/local/bin/irb19:12:in

def foo; 1; end
=> nil

“hello”.foo
NoMethodError: private method foo' called for "hello":String from (irb):3 from /usr/local/bin/irb19:12:in

Object.private_instance_methods.grep(/foo/)
=> [:foo]

I’m not sure why irb doesn’t define methods as singleton methods of the
‘main’ (top level) object. You can do this yourself with a bit of
fiddling:

class << self; self; end.class_eval { def bar; 2; end }
=> nil

bar
=> 2

1.bar
NoMethodError: undefined method bar' for 1:Fixnum from (irb):4 from /usr/local/bin/irb19:12:in

Deepak G. [email protected] writes:

foo.foo.foo ===>o/p 1
def foo
1
end

p foo
p foo.foo =>o/p private method `foo’ called for 1:Fixnum (NoMethodError)

How ??

Why? Ask youself why foo.foo.foo → 1 in the irb console!

Try: self.class
in both Scite and irb…

Pascal J. Bourguignon wrote:

Why? Ask youself why foo.foo.foo --> 1 in the irb console!

Try: self.class
in both Scite and irb…

It’s not quite as simple as just looking at ‘self’, and it took me a
long time to find out why.

Ruby has a concept of a ‘the current object’ which is exposed using
‘self’, but there is also a more hidden concept of ‘the current class’
where method definitions go. I don’t think there’s an easy way to see
the current class, but you can set it using class or class_eval.

class Foo; end
=> nil

Foo.instance_eval { p self }
Foo
=> nil

Foo.instance_eval { def bar; puts “bar”; end }
=> nil

Foo.bar
bar
=> nil

Foo.new.bar
NoMethodError: undefined method `bar’ for #Foo:0xb7c89710
from (irb):5
from :0

But:

Foo.class_eval { p self }
Foo
=> nil

Foo.class_eval { def baz; puts “baz”; end }
=> nil

Foo.baz
NoMethodError: undefined method `baz’ for Foo:Class
from (irb):8
from :0

Foo.new.baz
baz
=> nil

So in both cases, self is the class Foo, but in the first case methods
are defined in the singleton class of Foo, whilst in the second case
they are defined as instance methods in the class Foo.