2009-12-16 58 views
2

全码:http://friendpaste.com/5TdtGPZaEK0DbDBa2DCUyB的method_missing在instance_eval的

class Options 
    def method_missing(method, *args, &block) 
     p method 
    end 
end 

options = Options.new 

options.instance_eval do 
    foo 
    foo = "It aint easy being cheesy!" 
end 

puts "#===---" 
options.foo 
options.foo = "It still aint easy being cheesy!" 

这将返回:

:foo 
#===--- 
:foo 
:foo= 

因为它是治疗foo = ""为instance_eval的范围内的局部变量,它不承认它的方法。

我将如何使instance_eval将其视为一种方法?

+0

你想要什么'options.foo =“it aint ...”'要做什么? – klochner 2009-12-16 21:57:13

+0

在method_missing中被捕获,以供我操纵它,特别是在散列中设置键/值。它会像一个Struct一样工作。 – RyanScottLewis 2009-12-16 22:00:15

+0

查看完整的代码(链接在帖子的顶部) – RyanScottLewis 2009-12-16 22:01:17

回答

5

表达式foo = ""永远不会是方法调用。这是一个局部变量赋值。这是Ruby语法的一个事实。为了调用setter,你必须明确指定一个接收者。这就是为什么大多数Ruby伪DSL使用Dwemthy风格:

class Dragon < Creature 
    life 1340  # tough scales 
    strength 451 # bristling veins 
    charisma 1020 # toothy smile 
    weapon 939 # fire breath 
end 

这可以避免等号问题。

+0

哎呀,我为什么没有想到这个?那完美= D – RyanScottLewis 2009-12-16 22:38:50

2

self.foo = ""使它作为一种方法来对待它。

+0

是的,这将工作,我想。但我试图弄清楚的原因是,我不必使用self.foo或options.tap {| o | o.foo}运行方法=/ – RyanScottLewis 2009-12-16 21:23:18

+0

这里是我的完整代码,如果你有点麻烦:http://friendpaste.com/5TdtGPZaEK0DbDBa2DCUyB – RyanScottLewis 2009-12-16 21:24:04

+0

可悲的是,我不认为这是可能的。总是将'foo ='解释为局部变量赋值,并且无法获取块内定义的局部变量。 – mckeed 2009-12-16 22:08:52