Why is top-level an object rather than just Object?

J

John Mair

Why is it that top-level isn't just the Object class itself? what's the
rationale behind the 'main' object?
 
R

Robert Dober

Why is it that top-level isn't just the Object class itself? what's the
rationale behind the 'main' object?

Well the Object object, happening to be a module too (read class if
you prefer), is the parent of all ( almost all in Ruby 1.9) instances
in a Ruby program. For me it seems quite a good choice to
use an instance of Obejct to represent the top most "self" in a Ruby program.
It might be an instance of a special class like Toplevel (being a
singleton presumably), I would prefer that, but the actual approach is
a pragmatic one that is quite ok.

Now talking about your idea of main == Object I fail to see what that
should be good for. It is surely not the role of the (almost in Ruby
1.9) most general class in Ruby to carry the responsabilities of main.

Cheers
R
 
J

John Mair

But, for most cases main already behaves like Object:

* calling 'include' in main actually includes in Object
* defining a method in main actually defines the method on Object
* defining a constant in main actually defines the constant on Object

The only notable exception, where 'main' acts like itself (that is - as
an instance of Object) -- is instance variables. main has its own
instance variables independent of Object.

But i do not see a good reason not to just define the ivars on Object.

See this post:
http://banisterfiend.wordpress.com/2010/10/22/what-is-the-ruby-top-level/

John

Robert Dober wrote in post #956321:
 
R

Rick DeNatale

But, for most cases main already behaves like Object:

* calling 'include' in main actually includes in Object
* defining a method in main actually defines the method on Object
* defining a constant in main actually defines the constant on Object

I think there's some confusion here between self and the current
class, and also about the differences in the relationship between
classes and instances between Ruby and many other "OO" languages.

At the top level self refers to the top level object.

The current class is a separate value in the state of the ruby
interpreter/vm which determines which class or module statements like
def and include operate on. At the top level the current class is
Object, and methods get defined as private by default. This makes
them LOOK like functions rather than methods.
The only notable exception, where 'main' acts like itself (that is - as
an instance of Object) -- is instance variables. main has its own
instance variables independent of Object.

But i do not see a good reason not to just define the ivars on Object.

See this post:
http://banisterfiend.wordpress.com/2010/10/22/what-is-the-ruby-top-level/

And here is another difference between Ruby and languages you might be
"coming from." Instance variables are NOT "defined on" a class, but
are rather dynamically attached to instances as methods run.

http://talklikeaduck.denhaven2.com/2008/02/08/whose-variable-is-it-anyway

--
Rick DeNatale

Help fund my talk at Ruby Conf 2010:http://pledgie.com/campaigns/13677
Blog: http://talklikeaduck.denhaven2.com/
Github: http://github.com/rubyredrick
Twitter: @RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
 
R

Robert Dober

But, for most cases main already behaves like Object:

* calling 'include' in main actually includes in Object
true, but I do not think it is a good idea
* defining a method in main actually defines the method on Object
false; but as a private method, again I do not think it is a good idea
* defining a constant in main actually defines the constant on Object I buy this one

The only notable exception, where 'main' acts like itself (that is - as
an instance of Object) -- is instance variables. main has its own
instance variables independent of Object. finally a good idea ;)

But i do not see a good reason not to just define the ivars on Object.
Oh but I do, why should Object have instance variables of the
toplevel, if there are some good metaprogramming reasons to define
ivars on Object ... disaster.

That all said, I do not really care too much about toplevel as it
should not play a major role in any ruby application of consequent
size.

Cheers
Robert
 
J

John Mair

Rick Denatale wrote in post #956368:
I think there's some confusion here between self and the current
class, and also about the differences in the relationship between
classes and instances between Ruby and many other "OO" languages.

There is no confusion. I am aware that the 'default definee' (current
class) at top-level is Object and that this is different to the self at
top-level which is main.
At the top level self refers to the top level object.

I know.
The current class is a separate value in the state of the ruby
interpreter/vm which determines which class or module statements like
def and include operate on.

You're only half-right here. Default definee determines what 'def' works
on, but not include. At top-level 'include' is actually a singleton
method on main (see method:)include).owner) and its definition is
top_include() in eval.c where it explictly includes the module into
Object (did you read the blog post i linked earlier...?)
At the top level the current class is
Object, and methods get defined as private by default. This makes
them LOOK like functions rather than methods.

Ok. But i'm not debating this. :)
And here is another difference between Ruby and languages you might be
"coming from." Instance variables are NOT "defined on" a class, but
are rather dynamically attached to instances as methods run.

I don't know what you mean here. I was talking about the ivars on Object
- the *class* called Object. Classes can have ivars too, as im sure
you're aware: e.g:

class Hello
@x = 10
end

And these ivars ARE defined on an iv_tbl in the class (or at least on
the rb_classext_t member in the class).

I think we have been mainly talking at cross-purposes here. I do not
disagree with a lot of what you have said but I also do not see how it
is relevant. The point I was making was that:

(1) 'current class' and 'cref' at top-level are Object anyway, so
methods and constants will end up on Object.

(2) the top-level include method, although it is defined on main
(singleton class) actually includes into Object. Same with top-level
public and private methods.

(3) Instance variables, in so far as they're used (which i cant see what
for, really) may as well just be defined on the Object class (i mean
class instance variables here)

So i thknk if you just made Object the top-level context rather than
'main' you would get (1) and (2) for free (wouldn't' have to define any
weird singleton methods a la 'include') and (3) you may as put the ivars
on
Object class, ii can't really see any reason why not to :)

John
 
J

John Mair

Robert Dober wrote in post #956378:
true, but I do not think it is a good idea
false; but as a private method, again I do not think it is a good idea
Oh but I do, why should Object have instance variables of the
toplevel, if there are some good metaprogramming reasons to define
ivars on Object ... disaster.

Err, how exactly is it a disaster? can you explain? I can see no harm
coming from it. If you can see harm - then explain exactly what harm you
see rather than just communicating a vague sense of foreboding....hehe
;)

John
 
I

Intransition

Why is it that top-level isn't just the Object class itself? what's the
rationale behind the 'main' object?

It should not be. In fact, I think it is a mistake for main to
delegate to Object at all. It becomes a headache when trying to write
a scripting DSL. Rather than run the script at toplevel --which is
very nice b/c of the way #require works, one has to run the script in
a evaluation context so as to prevent pollution of every object. It is
easy enough to extend the Object class by opening it up or opening the
Kernel module, so this delegation is little more than a "nicety" --but
not a very nice one really.

Ideally main would simply be:

module Main
extend self
end
 
J

John Mair

Thomas Sawyer wrote in post #956386:
It should not be. In fact, I think it is a mistake for main to
delegate to Object at all. It becomes a headache when trying to write
a scripting DSL. Rather than run the script at toplevel --which is
very nice b/c of the way #require works, one has to run the script in
a evaluation context so as to prevent pollution of every object. It is
easy enough to extend the Object class by opening it up or opening the
Kernel module, so this delegation is little more than a "nicety" --but
not a very nice one really.

Ideally main would simply be:

module Main
extend self
end

I can kinda buy that argument, though i can see some problems with it
too. Like what would the semantics of 'class Hello' be at top-level
then? You'd obviously want it to define a constant on Object or else
you'd have to reference Main to get it out. But if you did have the
syntax 'class Hello' define a constant on Object then how would you nest
class/module constants conveniently? etc. I do kinda like your idea
though i just see some difficulties.

Nonetheless, back to the original point (if you're interested in
commenting on it.) Assuming top-level does maintain its current
behaviour, can you see any strong reasons why not to just replace 'main'
with Object? since 'main' as been patched and hacked up to act mostly
like Object anyway (by messing with cref and default definee and giving
it a bunch of class-like singleton methods), what would be the problem
in just having the top-level context being Object itself? (forgetting
for a minute your objections, but concentrating instead on replicating
the current behaviour but with a more elegant model)

banister
 
I

Intransition

Constant lookup would have to be adjusted to go through Object and
then on to Main.


It still has to differ at least slightly in that top-level methods
have to be private Object methods.

Also, top-level instance could cause also sorts of messy:

=A0 class X
=A0 =A0 def initialize(a)
=A0 =A0 =A0 @a =3D a
=A0 =A0 end
=A0 =A0 def to_s; @a.to_s; end
=A0 end

=A0 class Y
=A0 =A0 def initialize(a)
=A0 =A0 =A0 @a =3D a
=A0 =A0 end
=A0 =A0 def to_s; @a.to_s; end
=A0 end

=A0 x =3D Y.new(10)
=A0 y =3D Y.new(20)

=A0 puts x =A0#=3D> "10"
=A0 puts y =A0#=3D> "20"

=A0 @a =3D 30

=A0 puts x =A0#=3D> "30"
=A0 puts y =A0#=3D> "30"

My bad, that's not quite right. The @a would be at the class level,
so:

class X
def self.to_s
@a ||=3D 10
end
end

class Y
def self.to_s
@a ||=3D 20
end
end

puts X #=3D> "10"
puts Y #=3D> "20"

@a =3D 30

puts X #=3D> "30"
puts Y #=3D> "30"
 
R

Robert Dober

Robert Dober wrote in post #956378:

Err, how exactly is it a disaster? can you explain? I can see no harm
coming from it. If you can see harm - then explain exactly what harm you
see rather than just communicating a vague sense of foreboding....hehe
;
I believe that Tom (Intransition) has explained quite well. It is also
true that one could find workarounds if the ivars were declared in
Object, but it is a conceptional disaster.
Furthermore how nice and clean would that be ?

module Toplevel extend self
end

and then

Toplevel.instance_eval (or maybe module_eval) of the main script

implicitely of course ;).

Cheers
R.
 
J

John Mair

Thomas Sawyer wrote in post #956401:
My bad, that's not quite right. The @a would be at the class level,
so:

class X
def self.to_s
@a ||= 10
end
end

class Y
def self.to_s
@a ||= 20
end
end

puts X #=> "10"
puts Y #=> "20"

@a = 30

puts X #=> "30"
puts Y #=> "30"

@Thomas:

Dude, instance variables are not inherited in this way. Every object
gets its OWN instance variable table, including the Object class. There
is no confusion and no mix up, behold:

class X
def self.to_a
@a || = 10
end
end

class Y
def self.to_a
@a ||= 20
end
end

X #=> 10
Y #=> 20

class Object
@a = 30
end

X #=> 10
Y #=> 20

@a #=> 30

Having the instance variables on the Object class would NOT cause any of
the conflicts you guys are talking about :)

@Thomas, @Robert,

Have you guys checked out 'wrapped loads' ? In my edit to my previous
answer I wrote this:

"Have you checked out the 'load' function in Ruby? it has a feature
called 'wrapped loads' that loads the file into an anonymous module.
This means the loaded file cannot affect the global namespace and any
constants including classes and modules are trapped within the
anonymous module. Just call load with a second argument of anything
other than nil."

John
 
I

Intransition

Dude, instance variables are not inherited in this way. Every object
gets its OWN instance variable table, including the Object class. There
is no confusion and no mix up, behold:

class X
=A0 def self.to_a
=A0 =A0 @a || =3D 10
=A0 end
end

class Y
=A0 def self.to_a
=A0 =A0 @a ||=3D 20
=A0 end
end

X #=3D> 10
Y #=3D> 20

class Object
=A0 @a =3D 30
end

X #=3D> 10
Y #=3D> 20

@a #=3D> 30

Having the instance variables on the Object class would NOT cause any of
the conflicts you guys are talking about :)

You're right. I extrapolated from the instance case and made a
mistake.

It's still a bad idea to have main and Object intertwined for the
other reasons I have mentioned, so if anything changes I'd rather see
it change in that regard. But with regards to the current
functionality of Ruby, other than toplevel methods being made private,
I do not see any significant difference. As your correction to my
error points out, the toplevel instance variables are not currently
the same as Object class' instance variables. But I don't think it
would be a problem if they were. So you may well be right --main could
just as well be the Object class itself and everything would work as
before.

(Interestingly I played around with class variables (@@a) and they in
fact can be changed from the toplevel, effecting any class already.)
 

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,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top