我想在const_missing
中致电instance_eval
,但似乎遗漏了一些内容:
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)
}
问:const_missing
中instance_eval
的电话在哪里?如何将其重定向到班级A
? (Ruby 1.9.3,如果这很重要)
上下文:我正在编写一个小型DSL,其中大写字母用作州名。
DSL.evaluate {
ENTER_STATE_A
WAIT_FOR_INPUT
}
这些应该映射到方法,但我想保持大写。
答案 0 :(得分:2)
您正在尝试访问ruby正在解释为方法的常量w / a.MYCONST
。相反,您需要使用::
来访问类本身而不是该类的实例:
a = A.new
a.instance_eval {
self::class::MYCONST # => Constant missing: MYCONST
}
似乎在MYCONST
内拨打instance_eval
时,它被Object.const_missing
抓住了。例如,如果您覆盖它,则会看到您之后的行为:
def Object.const_missing(c)
puts "Constant missing: #{c}"
end
a = A.new
a.instance_eval {
MYCONST # => Constant missing: MYCONST
}
我不建议实际这样做。我只是为了说明发生了什么而展示了这一点。
答案 1 :(得分:1)
请注意,当你这样做时
a.MYCONST
你得到了Method missing: MYCONST
(而不是Constant missing: MYCONST
)。
您应该执行以下操作:
a.instance_eval {
myMethod
A::MYCONST
}