[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Re: openstruct oddity

Andreas S

12/7/2006 9:11:00 PM

>This one does not:
>
>module Foo
>def foo
> "foo"
>end
>end include Foo
>OpenStruct.new.foo
>=> foo
>
>This is surely an anomaly too, is it not?

Pardon my ignorance. I wasn't aware that the mixin module at top level
causes all its methods become globally available for all levels below.
Although, some comment on the explanation or reason behind this is
appreciated. (I was trying to turn my script into some script type by mixin
a module. Doesn't look like a good idea now)

-andre

_________________________________________________________________
Get the latest Windows Live Messenger 8.1 Beta version. Join now.
http://idea...


4 Answers

George

12/9/2006 8:51:00 AM

0

On 12/8/06, Andreas S <andreas_s@hotmail.com> wrote:
> Pardon my ignorance. I wasn't aware that the mixin module at top level
> causes all its methods become globally available for all levels below.
> Although, some comment on the explanation or reason behind this is
> appreciated.

At the top level, the "current object", self, is a particular instance
of Object (which I'll call 'main').

Now, main has some methods in its singleton class. Let's take a peek:

g@crash:~/tmp$ ruby -e 'p self.methods(false)'
["public", "include", "to_s", "private"]

So, when you do "include Foo" at the toplevel, this is, as always, the
same as "self.include(Foo)", which means call main's singleton class
method #include. This is defined to include things into Object.
Since everything derives from Object, the value of self at any point
in your code will be an Object, and so you can call Foo's methods
without a receiver.

Clever, huh?

Along a similar vein, ruby has the notion of the "current class".
This is like self in that it is defined at any point in your code, but
there's no short identifier for it. In fact, I can't think of a
(non-destructive, thread-safe) expression that will return it. But
this is the class that will gain a new method when you do "def foo".

So, at the toplevel, the "current class" is Object (not to be confused
with self, which is main). The current visibility is also "private",
so #foo will be a private method on Object. This lets you call #foo
from anywhere (again, because self will always be an Object), but will
cause an error if you do 3.foo or something, since #foo is private and
therefore can only be directly called without a receiver. You can,
incidentally, make the toplevel methods public. That's what the
#public is for up there in main's singleton class. Also note that in
irb, the default toplevel visibility is public, not private.
(Although I've noticed using a different context-mode, e.g., 'irb
--context-mode 0' changes this. Context modes are a whole other
novel, however, and should probably be explained by someone who knows
more than me. I invite them ;-).

Anyway, I know this is more than you asked for, but it took me a hunt
around the source a while ago to get to the bottom of it. So maybe I
can spare you, or someone else, the trek.

> (I was trying to turn my script into some script type by mixin
> a module. Doesn't look like a good idea now)

Sorry, I don't understand what you mean.

George

12/9/2006 8:56:00 AM

0

On 12/9/06, George Ogata <george.ogata@gmail.com> wrote:
>
> Along a similar vein, ruby has the notion of the "current class".
> This is like self in that it is defined at any point in your code, but
> there's no short identifier for it. In fact, I can't think of a
> (non-destructive, thread-safe) expression that will return it. But
> this is the class that will gain a new method when you do "def foo".

gsub(/class/, 'module') # :p

Vidar Hokstad

12/9/2006 1:16:00 PM

0


George Ogata wrote:
> On 12/8/06, Andreas S <andreas_s@hotmail.com> wrote:
> > Pardon my ignorance. I wasn't aware that the mixin module at top level
> > causes all its methods become globally available for all levels below.
> > Although, some comment on the explanation or reason behind this is
> > appreciated.
>
> At the top level, the "current object", self, is a particular instance
> of Object (which I'll call 'main').
>
> Now, main has some methods in its singleton class. Let's take a peek:
>
> g@crash:~/tmp$ ruby -e 'p self.methods(false)'
> ["public", "include", "to_s", "private"]
>
> So, when you do "include Foo" at the toplevel, this is, as always, the
> same as "self.include(Foo)", which means call main's singleton class
> method #include. This is defined to include things into Object.
> Since everything derives from Object, the value of self at any point
> in your code will be an Object, and so you can call Foo's methods
> without a receiver.
>
> Clever, huh?
>
> Along a similar vein, ruby has the notion of the "current class".
> This is like self in that it is defined at any point in your code, but
> there's no short identifier for it. In fact, I can't think of a
> (non-destructive, thread-safe) expression that will return it. But
> this is the class that will gain a new method when you do "def foo".

The current class (or module - I saw your correction) is in "self" when
you are outside a "def" or . It is just another object (of class
"Class" or "Module" respectively).

Try this:

class Foo
p self
p self.class
end

module Foo
p self
p self.class
end

If you are inside a "def" then it is "self.class", but in that case
"self.class" will refer to the class of the object you call the method
on, not the class or module the object was defined in.

Vidar

George

12/14/2006 4:51:00 AM

0

On 12/10/06, Vidar Hokstad <vidar.hokstad@gmail.com> wrote:
>
> George Ogata wrote:
> > Along a similar vein, ruby has the notion of the "current class".
> > This is like self in that it is defined at any point in your code, but
> > there's no short identifier for it. In fact, I can't think of a
> > (non-destructive, thread-safe) expression that will return it. But
> > this is the class that will gain a new method when you do "def foo".
>
> The current class (or module - I saw your correction) is in "self" when
> you are outside a "def" or . It is just another object (of class
> "Class" or "Module" respectively).
>
> Try this:
>
> class Foo
> p self
> p self.class
> end
>
> module Foo
> p self
> p self.class
> end
>
> If you are inside a "def" then it is "self.class", but in that case
> "self.class" will refer to the class of the object you call the method
> on, not the class or module the object was defined in.

You're correct (well, almost), but that's two expressions... ;-). And
ones where you have to know the context up front (statically). It falls short
on instance_eval. Inside an instance_eval block, the current module is
self's singleton class.

But I was just making the point that there is this bit of state that
exists on the C-side that isn't so clearly visible on the ruby one.
And that was, I think, the source of my confusion until I looked into
it.