Why can't I refer to constants nested inside a class within a module eval?
irb(main):001:0> class A
irb(main):002:1> class B
irb(main):003:2> end
irb(main):004:1> end
=> nil
irb(main):005:0> A.module_eval { puts B }
NameError: uninitialized constant B
from (irb):5
from (irb):5:in `module_eval'
from (irb):5
from :0
This is frustrating. Can anyone explain why it has to be this way? Perhaps there's a good reason I'm not considering.

Doing a module_eval of a block apparently leaves the constants bound in the block's context, not in the eval context. Try adding a top-level constant B = "surprise!" and do it again. But if you change the block to a string, it will bind B to A::B. Isn't Ruby fun sometimes?
Well it's really sad this is the case. I'm working on a solution to my gripes in the previous post that takes
describe "Something worth describing" do...and turns it into a sanitized/camelized Test::Unit style class with the contents of the block class evaluated inside of it. But if there are constant references in the block, they are bound globally, which kills test isolation. Look here:
It would be really nice if this defined
SomethingWorthDescribing::RarelyAViewso that I could use this constant freely within the test and not worry about other tests' usage of Foo.The Frankenstein welding of Rspec and Test::Unit is going well though. For now I can at least fall back on replacing the describe sugar with
SomethingWorthDescribingTest < Screw::Unit::TestCaseand still use other sugary Rspec syntax within it.You could do something like this:
Nathan, I remembered you when I read this post about the same problem where Ola Bini give you a real answer: