On Thu, May 1, 2008 at 8:31 PM, Ruby T. [email protected]
wrote:
Thanks for any ideas!
– Ara V.
Hi,
there doesn’t appear to be any form of block invocation that changes
how constants are looked up.
Some experiments:
X = :bad
module A
X = :good
class B
#…let us say I want to execute something here where X == :good
end
end
as you state, this doesn’t work
A.module_eval { X } # => :bad
nor this
A.instance_eval { X } # => :bad
nor this
A::B.new.instance_eval { X } # => :bad
this does of course
module A
X # => :good
end
and this
module A
class B
X # => :good
end
end
…but this surprised me
class A::B
X # => :bad
end
this doesn’t work either
context_A = A.module_eval { binding }
eval(“X”, context_A) # => :bad
you have to use a string
context_A = A.module_eval “binding”
eval(“X”, context_A) # => :good
but again
context_B = A::B.module_eval “binding”
eval(“X”, context_B) # => :bad
so you can’t parameterize this which means you have to do something
like:
def eval_in_namespace(namespace, str)
constants = []
namespace.split(/::/).reject{|x|
x.empty?}.inject(Module.const_get(self.class.to_s)) { |prev, this|
(constants << prev.const_get(this)).last
}
prefix = constants.map{ |x| “#{x.class.to_s.downcase} #{x}”}.join(’;’)
suffix = constants.map{ ‘end’}.join(’;’)
eval “#{prefix}; #{str}; #{suffix}”
end
eval_in_namespace(“A::B”, “X”) # => :good
not very pretty :S
of course, you could just use:
A::X # => :good
but not
A:
:X # => :bad # !> toplevel constant X referenced by A:
:X
Ara - could you shed some light on how continuations would help here?
I don’t see it myself.
Regards,
Sean