我已经解决了' Ruby koan 268,但它对我没有意义。该项目正在使用代理对象(我想作为一种适配器?)来模仿'电视课 以下是我的Proxy类的结果:
class Proxy
def initialize(target_object)
@object = target_object
# ADD MORE CODE HERE
attr_accessor :messages
@messages = []
end
# WRITE CODE HERE
def method_missing(method_name, *args)
if @object.respond_to?(method_name)
@messages.push(method_name)
@object.send(method_name, *args)
end
end
def messages
@messages
end
end
后来,代理电视宣布如下:
tv = Proxy.new(Television.new)
tv.power
tv.channel = 10
assert_equal [:power, :channel=], tv.messages
我的问题是,当我更早地定义了attr_accessor:消息时,为什么我必须将消息方法添加到Proxy?没有最后一种方法,公案就没有通过。 (tv.messages返回nil)。
我真的很想理解这一点,因为在我看来,我通过attr_accessor和messages方法定义访问@消息来重复自己。如果attr_accessor没有让我访问@messages,那么它的重点是什么?
感谢。
答案 0 :(得分:0)
我在ruby 2.1.5p273上运行了这段代码:
class A
def initialize
attr_accessor :m
end
def a(i)
@m = i
end
end
a = A.new
这会引发错误:
NoMethodError: undefined method `attr_accessor' for #<A:0x007f8313022220>
from (irb):3:in `initialize'
问题是attr_accessor
是一个类方法,而不是实例方法。因此,您无法从initialize
方法中调用它。你必须把它放在课外体内。然后它将正确设置访问器,它将首先按照您的预期工作:
class A
attr_accessor :m
def a(i)
@m = i
end
end
a = A.new
a.a 'hey'
a.m # => "hey"
答案 1 :(得分:0)
method_missing
的这个定义掩盖了错误:对非existant方法的任何调用只返回nil而不是引发NameError。
特别是您对attr_accessor
的调用没有做任何事情,因为attr_accessor
不是实例方法,因此调用method_missing
并吞下您的错误,因此您对{的定义需要{1}}才能获得messages
的值。如果您在@messages
方法之外致电attr_accessor
,那么initialize
的定义确实是多余的。
如果您省略了messages
方法,那么messages
只会调用proxy.messages
并且(除非电视有这样的方法)返回nil。