[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Why can't I get on Top?

Trans

10/2/2006 12:33:00 AM

More Toplevel blow:

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

Produces:

false

:-(

T.

16 Answers

MonkeeSage

10/2/2006 1:03:00 AM

0

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

dblack

10/2/2006 1:26:00 AM

0

MonkeeSage

10/2/2006 1:57:00 AM

0

dblack@wobblini.net 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. ;)

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

10/2/2006 4:23:00 AM

0


dblack@wobblini.net 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.

Jeff Schwab

10/2/2006 6:56:00 AM

0

MonkeeSage wrote:
> 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
>

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

class << self

# $toplevel has to be set in here,
# where it can really refer to the
# including object.

$toplevel = self
include Test
end

MonkeeSage

10/2/2006 7:02:00 AM

0

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?(C) # => 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

Timothy Goddard

10/2/2006 7:29:00 AM

0

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.

MonkeeSage wrote:
> 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?(C) # => 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

dblack

10/2/2006 10:11:00 AM

0

dblack

10/2/2006 11:29:00 AM

0

Trans

10/2/2006 12:08:00 PM

0


Jeffrey Schwab wrote:

> module Test
> def self.included( base )
> p base == $toplevel
> end
> end
>
> class << self
>
> # $toplevel has to be set in here,
> # where it can really refer to the
> # including object.
>
> $toplevel = self
> include Test
> end

In your example you are controlling the inclusion from the start.
That's missing the point. The #included callback catches the inclusion
of a module and _reacts_ to that. The module is a resuable lib that an
end-user/programmer may well include at the toplevel and the module
should just work. Otherwise one has to document: "IMPORTANT: don't
include at toplevel, It won't work...."

But you also may not realize that methods defined at the toplevel do
not go to the singleton. They go to Object itself. So really your
example should be:

class Object
$toplevel = self
include Test
end

But you are getting a false positive, since:

module NotTheTopLevel
$toplevel = self
include Test
end

works too.

T.