Consider this:
[snip]
It produces [M1::M2::C], which I did not expect. Why the difference?
Quoted form RI
“Returns the list of +Modules+ nested at the point of call.”
The ‘puts’ occurs at 3 levels of nesting.
There is no modules surrounding ‘p’…
Does that help ?
ruby -v
ruby 1.9.0 (2004-04-06) [i386-freebsd5.1]
ruby a.rb
[M1::M2::C, M1::M2, M1]
[M1::M2::C]
expand -t2 a.rb
module M1
module M2
class C
puts Module.nesting.inspect
end
end
end
p M1::M2::C.class_eval(“Module.nesting”)
···
On Tue, 13 Apr 2004 07:15:58 +0900, Brian Marick wrote:
module M1
module M2
class C
puts Module.nesting.inspect
end
end
end
It produces [M1::M2::C, M1::M2, M1], which I expected.
Now try this:
M1::M2::C.class_eval(“Module.nesting”)
It produces [M1::M2::C], which I did not expect. Why the difference?
Thanks.
It’s returning the proper nesting. But as you haven’t opened each of
the Modules individually to reach the C const, Module::nesting isn’t
returning them each individual.
Let’s illustrate:
module M1::M2
class C
puts Module.nesting.inspect
end
end
#=> [M1::M2::C, M1::M2]
This strikes me as being a bit unintuitive, though I don’t ever really
need it so I’m not too bothered.
It appears that this behavior is a remnant of the way Ruby is parsed
(or, more correctly, how it’s eval(.c)uated). Brian, were you using
this for your automock thing?
I’m interested to hear what other uses people have found for this
method.
Chad
···
On 12/4/2004, at 9:26 PM, why the lucky stiff wrote:
Brian Marick wrote:
Consider this:
module M1
module M2
class C
puts Module.nesting.inspect
end
end
end
It produces [M1::M2::C, M1::M2, M1], which I expected.
Now try this:
M1::M2::C.class_eval(“Module.nesting”)
It produces [M1::M2::C], which I did not expect. Why the difference?
Thanks.
It’s returning the proper nesting. But as you haven’t opened each of
the Modules individually to reach the C const, Module::nesting isn’t
returning them each individual.
Let’s illustrate:
module M1::M2
class C
puts Module.nesting.inspect
end
end
#=> [M1::M2::C, M1::M2]
module M1
module M2
class C
puts Module.nesting.inspect
end
end
end
It produces [M1::M2::C, M1::M2, M1], which I expected.
Now try this:
M1::M2::C.class_eval(“Module.nesting”)
It produces [M1::M2::C], which I did not expect. Why the difference?
Thanks.
It’s returning the proper nesting. But as you haven’t opened each of
the Modules individually to reach the C const, Module::nesting isn’t
returning them each individual.
Let’s illustrate:
module M1::M2
class C
puts Module.nesting.inspect
end
end
#=> [M1::M2::C, M1::M2]
This strikes me as being a bit unintuitive, though I don’t ever really
need it so I’m not too bothered.
It’s similar to the way constant definitions are scoped:
irb(main):001:0> module A; X=1; module B; p X; end; end
1
=> nil
irb(main):002:0> module A::B; p X; end
NameError: uninitialized constant A::X
from (irb):2
irb(main):003:0> module A::B; p A::X; end
1
i.e., if you say “module A::B” it’s different from entering one level
at a time. (I don’t think this syntax existed in pre-1.8, but I guess
the idea as applied to Module.nesting was similar.)
I’m interested to hear what other uses people have found for this
method.
None. In fact, until today I didn’t know (or had forgotten) that it
existed.
David
···
On Tue, 13 Apr 2004, Chad Fowler wrote:
On 12/4/2004, at 9:26 PM, why the lucky stiff wrote:
module M1
module M2
class C
puts Module.nesting.inspect
end
end
end
It produces [M1::M2::C, M1::M2, M1], which I expected.
Now try this:
M1::M2::C.class_eval(“Module.nesting”)
It produces [M1::M2::C], which I did not expect. Why the difference?
Thanks.
It’s returning the proper nesting. But as you haven’t opened each of
the Modules individually to reach the C const, Module::nesting isn’t
returning them each individual.
Let’s illustrate:
module M1::M2
class C
puts Module.nesting.inspect
end
end
#=> [M1::M2::C, M1::M2]
This strikes me as being a bit unintuitive, though I don’t ever really
need it so I’m not too bothered.
It seems unintuitive to me as well. I thought it would tell me about
the runtime module-nesting structure of the program, not about the
syntax by which I’m talking about that structure.
It appears that this behavior is a remnant of the way Ruby is parsed
(or, more correctly, how it’s eval(.c)uated). Brian, were you using
this for your automock thing?
module M1
module M2
class C
puts Module.nesting.inspect
end
end
end
It produces [M1::M2::C, M1::M2, M1], which I expected.
Now try this:
M1::M2::C.class_eval(“Module.nesting”)
It produces [M1::M2::C], which I did not expect. Why the difference?
Thanks.
It’s returning the proper nesting. But as you haven’t opened each of
the Modules individually to reach the C const, Module::nesting isn’t
returning them each individual.
Let’s illustrate:
module M1::M2
class C
puts Module.nesting.inspect
end
end
#=> [M1::M2::C, M1::M2]
This strikes me as being a bit unintuitive, though I don’t ever really
need it so I’m not too bothered.
It seems unintuitive to me as well. I thought it would tell me about the
runtime module-nesting structure of the program, not about the syntax by
which I’m talking about that structure.
I guess the value returned by #nesting has to be lexically determined
because ruby classes can be reopened. The following prints two different
nestings:
module M1
module M2
class C
puts Module.nesting.inspect
end
end
end
module M3
module M4
class C
puts Module.nesting.inspect
end
end
end
So there really is no “runtime” nesting structure. The nesting only
exists while the interpreter is evaluating code inside it.
···
On Apr 12, 2004, at 9:32 PM, Chad Fowler wrote:
On 12/4/2004, at 9:26 PM, why the lucky stiff wrote:
I guess the value returned by #nesting has to be lexically determined
because ruby classes can be reopened. The following prints two different
nestings:
module M1
module M2
class C
puts Module.nesting.inspect
end
end
end
module M3
module M4
class C
puts Module.nesting.inspect
end
end
end
So there really is no “runtime” nesting structure. The nesting only
exists while the interpreter is evaluating code inside it.
Here is another scriptlet demonstrating your point
module T
end
module Outer
module Inner
C = ::T
module C
$c = binding
end
end
end
class A
B = ::T
module B
$b = binding
end
end
p eval(“Module.nesting”,$c)
p eval(“Module.nesting”,$b)
Thanks for the very clear demonstration Christoph!
This issue of lexical code nesting vs ‘intuitive’ class/module nesting
isn’t widely documented, but goes further than affecting just
Module.nesting. Its tentacles tickle the corner cases for class
variable and constant lookup, particularly when ‘class X::Y’ style
declarations are used.
E:>type nesting.rb
class A
X = 1
class B
$b = self
puts "class A; class B"
puts X
end
end
class A::B
puts "Same class as previously? #{self == $b}"
puts "class A::B"
puts X
end
E:>ruby -v nesting.rb
ruby 1.8.1 (2004-01-27) [i386-mswin32]
class A; class B
1
Same class as previously? true
class A::B
nesting.rb:13: uninitialized constant A::X (NameError)