创建一个新的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]
有没有人知道发生了什么?
答案 0 :(得分:5)
某些地方正在为YAML提供Psych
内容。精神patches Kernel
添加psych_y
方法,该方法别名为y
。因此,所有内容都定义了y
方法:
> o = OpenStruct.new
> o.method(:y)
=> #<Method: OpenStruct(Kernel)#psych_y>
AFAIK,OpenStruct使用method_missing
和内部Hash来生成访问器和mutator方法;但是,从内核的“友好”补丁中已经有y
,因此OpenStruct的魔法无法处理y
方法,因为Psych的魔法正在阻碍。变异符y=
很好,但您可以放心o.y = 11
并在11
内看到o
。
你可以像这样删除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
那样基本的东西。