Why can't I get on Top?

More Toplevel blow:

$toplevel = self
module Test
def self.included( base )
p base == $toplevel
end
end
include Test

Produces:

false

:frowning:

T.

Trans wrote:

Produces:

false

That’s correct. In that case self is an instance of Object


module Test
def test
puts ‘hi’
end
end
class << self
include Test
end
test


but Module#included tells you the module or class of the including
scope; it doesn’t pass the instance itself.

Regards,
Jordan

Hi –

On Mon, 2 Oct 2006, MonkeeSage wrote:

end
end
class << self
include Test
end
test


but Module#included tells you the module or class of the including
scope; it doesn’t pass the instance itself.

Yes it does: the instance itself is a Module (or Class) :slight_smile: There’s
no translation or looking up necessary:

class C
include M # the method “include” is called on the object C
end

The top level is a bit anomalous: ‘self’ is not a Module or Class, but
it does some proxying for Object. So if you do:

include M

at the top level, it’s as if you’d done:

class Object
include M
end

David

[email protected] wrote:

The top level is a bit anomalous: ‘self’ is not a Module or Class, but
it does some proxying for Object. So if you do:

include M

at the top level, it’s as if you’d done:

class Object
include M
end

That’s what I was trying to say. :wink:

But main is an instance of Object, isn’t it? At least, it acts like
one. Thus singleton methods:

class << self
include Test
end

And class membership:

p self.class

Regards,
Jordan

Trans wrote:

Yes, but so is everything.

Hmmm
I’m not the sharpest tool in the shed, but I don’t think that is
correct. There are first-order objects like classes and modules.
Normally #included gets the class or module object itself, not an
instance. At least that’s how I’ve always thought it worked.

module Test
def self.included(base)
p base.instance_of?© # => false
base.module_eval { # <- extends the actual class, not an instance
def m
puts ‘Howdy do’
end
}
end
end
class C
include Test
end
C.new.m

Regards,
Jordan

[email protected] wrote:

The top level is a bit anomalous: ‘self’ is not a Module or Class, but
it does some proxying for Object. So if you do:

Right. So how does one catch if a module is included at the toplevel
then?

MonkeeSage wrote:

But main is an instance of Object, isn’t it? At least, it acts like
one. Thus singleton methods:

Yes, but so is everything.

I really wish someone would tell me what’s wrong with a self extended
module for toplevel instead of this silly proxy of Object.

T.

The base level in Ruby runs in the context of an instance of Object.
When you add base level methods you’re actually adding those methods to
the eigenclass of the main object. The main object in essence is an
instance of its eigenclass and the eigenclass is a subclass of the
Object class. You can do this with any Ruby object (except Fixnums,
which is an annoying inconsistency):

irb(main):010:0> a = “Frog”
=> “Frog”

irb(main):011:0> def a.double
irb(main):012:1> self * 2
irb(main):013:1> end
=> nil

irb(main):014:0> a.double
=> “FrogFrog”

irb(main):015:0> b = “Camel”
=> “Camel”

irb(main):016:0> b.double
NoMethodError: undefined method `double’ for “Camel”:String
from (irb):16
from :0

Note that the original String class isn’t affected - the method has
been added to the eigenclass of object a.

Hi –

On Mon, 2 Oct 2006, Timothy G. wrote:

The base level in Ruby runs in the context of an instance of Object.
When you add base level methods you’re actually adding those methods to
the eigenclass of the main object. The main object in essence is an
instance of its eigenclass and the eigenclass is a subclass of the
Object class. You can do this with any Ruby object (except Fixnums,
which is an annoying inconsistency):

The singleton class/object relationship isn’t quite an instance one;
it’s a little more “phantom”-like. It doesn’t add a real level to the
“family tree”; an object is still an instance of the thing it was an
instance of before:

class C; end
class D < C; end

d = D.new
sing = class << d; self; end

p D.new.instance_of?© # false
p D.new.instance_of?(D) # true
p D.new.instance_of?(sing) # false

So thinking of the singleton class as a subclass of the object’s class
might be a little misleading, since the object still relates to its
“birth class” at only one level of remove.

David

On 10/2/06, [email protected] [email protected] wrote:

p D.new.instance_of?(C) # false
p D.new.instance_of?(D) # true
p D.new.instance_of?(sing) # false

So thinking of the singleton class as a subclass of the object’s class
might be a little misleading, since the object still relates to its
“birth class” at only one level of remove.

Of course, but what I am puzzeled about is, why you use #instance_of?,
well
not really, because that was how the argument began.
As a matter of fact let me be more humble :wink:
I am afraid I missed something basic in the discussion, because to my
understanding #instance_of? is irrelevant and #is_a?
is what we are interested in, no? (obviously no ;).
Thx
Robert

Hi –

On Mon, 2 Oct 2006, Robert D. wrote:

not really, because that was how the argument began.
As a matter of fact let me be more humble :wink:
I am afraid I missed something basic in the discussion, because to my
understanding #instance_of? is irrelevant and #is_a?
is what we are interested in, no? (obviously no ;).

I was responding to Timothy’s description of the default object main
as an instance of its singleton class. My point was that the
relationship between an object and its singleton class is not actually
defined by Ruby as a class-instance relationship, though of course it
is very similar to such a relationship in many ways.

David

On Mon, Oct 02, 2006 at 09:35:11AM +0900, Trans wrote:

Produces:

false

:frowning:

I wonder if the powers that be would consider adding some additional
hooks if they don;t want to make the top-level an extended self module.

(e.g:

alias toplevel_include include
def include(mod)
toplevel_include( mod )
mod.included( self )
end

I don’t really like that actually. Trans, consider my vote added in
favor to “Make the toplevel a self-extended module”. It just seems so
much more useful and cleaner without this silly proxying.

Timothy G. wrote:

The base level in Ruby runs in the context of an instance of Object.
When you add base level methods you’re actually adding those methods to
the eigenclass of the main object.

That’s not correct. The methods are being added to Object itself. Main
is just a proxy. The methods is has related to defining and looking up
methods just reroute to Object.

def x; end
p Object.private_instance_methods(false)
=> [‘initialize’, ‘x’]

To add to the toplevel pot:

def x; end
respond_to?(:x)
=> false

(I know, b/c it’s private method, but still.)

T.

Hi Trans,

How about a workaround for now? Something like:

class << self
def include(mod)
self.extend(mod)
if in_toplevel?
p ‘Do NOT use me from toplevel’
end
end
end

module NoTopLevel
def in_toplevel?
self.to_s == ‘main’
end
end

include NoTopLevel

Regards,
Jordan

On 10/2/06, [email protected] [email protected] wrote:

class C; end
might be a little misleading, since the object still relates to its

I was responding to Timothy’s description of the default object main
as an instance of its singleton class.

Yes I pointed that out


My point was that the

relationship between an object and its singleton class is not actually
defined by Ruby as a class-instance relationship, though of course it
is very similar to such a relationship in many ways.


 but I got confused with the original concept, I did not realize that
you
drifted OT, which is not a bad thing.
Your clarifications will save me some time as I was intrigued in which
way
the
instance_of_ness of the main object would be relevant, and I guess it is
not.
Thx
Robert

David

Trans wrote:

That catches it, although it also catches when Taskable is included in
Object too. But that’s only one exception that won’t cause any harm, so
it’s an accecptable work around.

Right on. I just realized that my last suggestion was retarded anyhow,
since in_toplevel? had to be true, always, since I was only
overriding #include as a singleton method of the main instance. Doh
(guess I’m still not the sharpest tool!).

Regards,
Jordan

MonkeeSage wrote:

end
end

module NoTopLevel
def in_toplevel?
self.to_s == ‘main’
end
end

include NoTopLevel

Well, let me show you what I’m actually doing:

module Taskable
def self.included( base )
if base.toplevel?
require ‘main_as_module.rb’
end
end
end

main_as_module.rb is actually a bit of code that will add every module
method there is to toplevel (ie. main). So you see I’m actually trying
to selectively mitigate the issue were talking about. I could just
require this lib no matter what and be done with it, but I thought it
would be better if I only included it if it is needed --no sense in
loading code that’s not used. But it looks like I don’t have much
choice. However, I did manage this work-around:

module Taskable
def self.included( base )
if base == Object
require ‘main_as_module.rb’
end
end
end

That catches it, although it also catches when Taskable is included in
Object too. But that’s only one exception that won’t cause any harm, so
it’s an accecptable work around.

T.