创建一个新的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]
有人知道发生了什么吗?
某个地方正在为YAML的东西Psych
。心理补丁Kernel
添加一个别名为y
的psych_y
方法。因此,一切都定义了y
方法:
> o = OpenStruct.new
> o.method(:y)
=> #<Method: OpenStruct(Kernel)#psych_y>
AFAIK,OpenStruct使用method_missing
和内部哈希来生成访问器和突变器方法;但是,从这个"友好"补丁到内核已经有一个y
,所以OpenStruct的魔力无法处理y
方法,因为Psych的魔力阻碍了。突变器y=
很好,因此您可以安全地o.y = 11
并在o
内查看您的11
。
您可以像这样删除y
:
> o = OpenStruct.new
> o.class_eval('undef_method :y')
> o.y = 11
> o.y
=> 11
您可能可以从Kernel
中删除该方法,并希望没有什么取决于那个愚蠢的y
别名:
> Kernel.send(:undef_method, :y)
> o = OpenStruct.new
> o.y = 11
> o.y
=> 11
或者你可以把它从OpenStruct
中删除:
> OpenStruct.send(:undef_method, :y)
> o = OpenStruct.new
> o.y = 11
> o.y
=> 11
这种事情就是为什么很多人不喜欢猴子补丁的原因,尤其是猴子修补像Kernel
这样基本的东西。