Re: openstruct oddity

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

On 12/8/06, Andreas S [email protected] 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.

On 12/9/06, George O. [email protected] 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’) # :stuck_out_tongue:

George O. wrote:

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

On 12/10/06, Vidar H. [email protected] wrote:

“Class” or “Module” respectively).
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.