I would like to call const_missing
in an instance_eval
, but seem to be missing something:
class A
def self.const_missing(c)
puts "Constant missing: #{c}"
end
def method_missing(m, *args, &block)
puts "Method missing: #{m}"
end
end
# Works:
a = A.new
a.myMethod # OK: "Method missing: myMethod"
a.MYCONST # Sort of OK: "Method missing: MYCONST"
# Doesn't work
a.instance_eval {
myMethod # OK: "Method missing: myMethod"
MYCONST # uninitialized constant MYCONST (NameError)
}
Q: Where does the const_missing
call in the instance_eval
go? How can redirect it to class A
? (Ruby 1.9.3 if this matters)
Context: I am writing a small DSL, where upper-case letters are used as state names.
DSL.evaluate {
ENTER_STATE_A
WAIT_FOR_INPUT
}
These should be mapped to methods, but I would like to keep them upper case.
You're trying to access a constant w/ a.MYCONST
which ruby is interpreting as a method. You instead need to use ::
along w/ access the class itself and not the instance of that class:
a = A.new
a.instance_eval {
self::class::MYCONST # => Constant missing: MYCONST
}
It seems that when calling MYCONST
inside of instance_eval
it's being caught by Object.const_missing
. For example if you override it you'll see the behavior you're after:
def Object.const_missing(c)
puts "Constant missing: #{c}"
end
a = A.new
a.instance_eval {
MYCONST # => Constant missing: MYCONST
}
I don't recommend actually doing this though. I'm only showing this to illustrate what's happening.
Note that when you do
a.MYCONST
you got Method missing: MYCONST
(and not Constant missing: MYCONST
).
You should do the following:
a.instance_eval {
myMethod
A::MYCONST
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.