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

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

On Fri, Oct 22, 2010 at 11:51 AM, John M. [email protected] wrote:

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

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 D. wrote in post #956321:

On Fri, Oct 22, 2010 at 11:51 AM, John M. [email protected] wrote:

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

On Fri, Oct 22, 2010 at 11:07 AM, John M. [email protected] wrote:

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

Rick Denatale wrote in post #956368:

On Fri, Oct 22, 2010 at 11:07 AM, John M. [email protected] wrote:

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.

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. :slight_smile:

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.

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 :slight_smile:

John

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

Robert D. wrote in post #956378:

On Fri, Oct 22, 2010 at 5:07 PM, John M. [email protected] wrote:

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 :wink:

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.

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
:wink:

John

EDIT: btw those weren’t ‘ideas’ i was just describing the actual
behaviour. Test it and see :slight_smile:

On Fri, Oct 22, 2010 at 5:07 PM, John M. [email protected] wrote:

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 :wink:

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

On Oct 22, 5:51 am, John M. [email protected] wrote:

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

Thomas S. wrote in post #956386:

On Oct 22, 5:51 am, John M. [email protected] wrote:

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

EDIT: 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.

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)

John

On Oct 22, 2:55pm, John M. [email protected] wrote:

a scripting DSL. Rather than run the script at toplevel --which is
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.

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

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)

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:

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

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

x = Y.new(10)
y = Y.new(20)

puts x #=> “10”
puts y #=> “20”

@a = 30

puts x #=> “30”
puts y #=> “30”

On Fri, Oct 22, 2010 at 8:28 PM, John M. [email protected] wrote:

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.

On Oct 22, 3:36pm, Intransition [email protected] wrote:

It should not be. In fact, I think it is a mistake for main to
module Main

for a minute your objections, but concentrating instead on replicating
end
x = Y.new(10)
y = Y.new(20)

puts x #=> “10”
puts y #=> “20”

@a = 30

puts x #=> “30”
puts y #=> “30”

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 S. wrote in post #956401:

On Oct 22, 3:36pm, Intransition [email protected] wrote:

It should not be. In fact, I think it is a mistake for main to
module Main

for a minute your objections, but concentrating instead on replicating
end
x = Y.new(10)
y = Y.new(20)

puts x #=> “10”
puts y #=> “20”

@a = 30

puts x #=> “30”
puts y #=> “30”

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 :slight_smile:

@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

On Oct 23, 1:06am, John M. [email protected] wrote:

class Y
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 :slight_smile:

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.)

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs