在创建一个新的ruby openstruct对象之后,我可以存储属性,但不能检索它们(我得到一个空行,它返回nil
):
obj = OpenStruct.new # => #<OpenStruct>
obj.x = 10
obj.y = 20
obj # => #<OpenStruct x=10, y=20>
obj.x # => 10
obj.y #
# => nil
如果我尝试用不同的名称存储其他属性,则一切都按预期工作。只有当我存储名为
y
的属性时,才会出现此问题。我正在使用以下版本:ruby 1.9.2p320 (2012-04-20 revision 35421) [i686-linux]
有人知道发生了什么事吗?
最佳答案
某处有什么东西在偷山药。psychPsych
添加一个别名为Kernel
的psych_y
方法。所以,所有东西都定义了一个y
方法:
> o = OpenStruct.new
> o.method(:y)
=> #<Method: OpenStruct(Kernel)#psych_y>
另外,openstruct使用patches
y
和一个内部散列来生成访问器和变异器方法;但是,已经有一个method_missing
从“友好”补丁到内核,所以openstruct的魔力无法处理y
方法,因为psych的魔力挡在了路上。突变子y
很好,所以你可以安全地y=
看到你的o.y = 11
在11
里面。您可以这样删除
o
:> o = OpenStruct.new
> o.class_eval('undef_method :y')
> o.y = 11
> o.y
=> 11
您可能会从
y
中删除该方法,并希望没有什么依赖于那个愚蠢的Kernel
别名:> Kernel.send(:undef_method, :y)
> o = OpenStruct.new
> o.y = 11
> o.y
=> 11
或者你可以从
y
中删除它:> OpenStruct.send(:undef_method, :y)
> o = OpenStruct.new
> o.y = 11
> o.y
=> 11
这就是为什么很多人不喜欢猴子补丁,特别是像
OpenStruct
这样基本的东西。