A question about Ruby main object


#1

Hi!

I have been doing different things w/ Ruby for a couple of years now
and
the only bad thing I can say about it is that it makes programming in
other
languages feel awfully burdensome. = )

Anyhow, I really like how everything makes sense. There is one thing
that
I have not been able to fit in entirely. A Ruby program starts in the
context of the “main” object,

antti@hyperion:~> ruby -e “puts self”
main
antti@hyperion:~> ruby -e “puts self.class”
Object

However, the methods I declare in the context of this “main” object
are
somehow available as private methods of class Object (and naturally
usable
from subclasses):

def foo
puts “hello”
end
class Bar
def amethod
foo
end
end
b = Bar.new
b.amethod

outputs:
hello

Is there some 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:

antti@hyperion:~> ruby -e “puts self.kind_of?(Class)”
false
antti@hyperion:~> ruby -e “puts self.kind_of?(Module)”
false

So what is the logic behind the “main” object? Is there a logical
reason
for the methods defined in its context to appear as private methods of
class Object?

    -Antti-

#2

See

http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/7bb7b451a8f3cca7/98c4c62127b9d945?q=itsme213+main+singleton+Object&rnum=1#98c4c62127b9d945

“Antti Karanta” removed_email_address@domain.invalid wrote in
message
news:dpbr1c$p2b$removed_email_address@domain.invalid…


#3

Antti Karanta wrote:

Is there some 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:

Note that you are not doing def self.method() end. It’s just that def
method() end at the top level adds the methods to the Kernel module
(which is included in Object meaning its methods are available
everywhere) instead of raising an exception or adding them to the top
level object itself.

It’s also interesting to see which singleton methods the top level
object has:

ruby -e “p methods(false)”
[“include”, “private”, “to_s”, “public”]

to_s is so you see “main” when doing p self etc. at the top level.
The other three ones are top level versions of the respective instance
method of Module.


#4

Antti Karanta wrote:

So what is the logic behind the “main” object? Is there a logical reason
for the methods defined in its context to appear as private methods of
class Object?

To quote Guy Decoux:

when you define a method in A, this will be an instance method for A

Now, I have a question for Guy:

Flagellate = Class.new {
def banana_boat; puts ‘hurrah!’ end
}

makes banana_boat a method on Flagellate, which makes me think that
methods go where self is.

However:

class FranklinRoosevelt
def smooth_operator; def banana_boat; puts ‘javohl!’ end end
end
FranklinRoosevelt.new.smooth_operator

makes banana_boat a method on FranklinRoosevelt, which is either
ruby_class or self.class, but not self.

What’s goin’ on? Is there another internal variable that determines
where methods go, or am I confusing things? Are Class.new and class_eval
just the exception to the rule that method definitions go on ruby_class?
If so, how?

Devin


#5

“t” == ts removed_email_address@domain.invalid writes:

t> many persons will except that ruby will do the same that if you
write
^^^^^^
expect

l’anglais est vraiment tres etrange :slight_smile:

Guy Decoux


#6

“D” == Devin M. removed_email_address@domain.invalid writes:

D> Flagellate = Class.new {
D> def banana_boat; puts ‘hurrah!’ end
D> }

With this you have this case

  • in the class A, it has : self = A, ruby_class = A

This mean that you have self = ruby_class = Flagellate

D> However:

D> class FranklinRoosevelt
D> def smooth_operator; def banana_boat; puts ‘javohl!’ end end
D> end
D> FranklinRoosevelt.new.smooth_operator

D> makes banana_boat a method on FranklinRoosevelt, which is either
D> ruby_class or self.class, but not self.

When the method #smoot_operator is called

  • self is an instance of FranklinRoosevelt
  • ruby_class is FranklinRoosevelt

#banana_boot become a method on FranklinRoosevelt

D> What’s goin’ on? Is there another internal variable that determines
D> where methods go, or am I confusing things?

You are confusing : the problem is that you can’t access the variable
ruby_class, it’s completely hidden but ruby always use this variable to
know where it must store a method.

D> Are Class.new and class_eval just the exception to the rule that
method
D> definitions go on ruby_class? If so, how?

No, they are not exceptions. This is just that when you write

Flagellate = Class.new {
def banana_boat; puts ‘hurrah!’ end
}

many persons will except that ruby will do the same that if you write

class Flagellate
def banana_boat; puts ‘hurrah!’ end
end

This is why it define self = ruby_class = Flagellate

Guy Decoux


#7

“D” == Devin M. removed_email_address@domain.invalid writes:

D> Thanks. It turns out my confusion is with constants and
class-variables
D> (whose destination I’d figured was based on ruby_class), not methods,
D> since:

Perhaps best to don’t speak about class-variable because it seems to be
a
true POLS, i.e. only matz is not surprised :slight_smile:

D> Loves me some complex grammar rules…

It don’t exist complex grammar rules, ruby just try to follow matz’s
POLS

Guy Decoux


#8

ts wrote:

t> many persons will except that ruby will do the same that if you write
^^^^^^
expect

l’anglais est vraiment tres etrange :slight_smile:

Nah… 'snot that bad… :slight_smile:

Thanks. It turns out my confusion is with constants and class-variables
(whose destination I’d figured was based on ruby_class), not methods,
since:

irb(main):001:0> Foo = Class.new {
irb(main):002:1* FOO = 5
irb(main):003:1> }
=> Foo
irb(main):004:0> FOO
=> 5
irb(main):005:0> Foo.class_eval {
irb(main):006:1* @@foo = 5
irb(main):007:1> }
=> 5
irb(main):008:0> @@foo
=> 5

What determines where they go?

Thanks,
Devin
Loves me some complex grammar rules…


#9

Quoting ts removed_email_address@domain.invalid:

D> Loves me some complex grammar rules…

It don’t exist complex grammar rules, ruby just try to follow
matz’s POLS

I can assure you that the Ruby grammar has pretty complex rules if
you’re interested in parsing it.

-mental


#10

ts wrote:

D> Loves me some complex grammar rules…

It don’t exist complex grammar rules, ruby just try to follow matz’s POLS

I was talking about English… :stuck_out_tongue:


#11

itsme213 wrote:

See

http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/7bb7b451a8f3cca7/98c4c62127b9d945?q=itsme213+main+singleton+Object&rnum=1#98c4c62127b9d945

Thanks, this cleared it up. Weird I did not bump into that thread w/
google…

   -Antti-