2012-11-04 34 views
4

创建一个新的Ruby OpenStruct对象后,我能够存储属性,但不能对它们进行检索(我得到一个空行,并返回nil代替):OpenStruct.new存储属性,但不会检索

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]

有谁知道发生了什么事情的想法?

回答

5

一些地方在Psych拉动了YAML的东西。迷幻patches Kernel添加psych_y方法,其别名为y。所以,一切都具有已定义的方法y

> o = OpenStruct.new 
> o.method(:y) 
=> #<Method: OpenStruct(Kernel)#psych_y> 

AFAIK,OpenStruct使用method_missing和内部散列以产生存取器和mutator方法;但是从Kernel的“友好”补丁已经有一个y,所以OpenStruct的魔法无法处理y方法,因为Psych的魔法已经出现了。该突变,y=,是好的,但这样你可以放心地o.y = 11,看看你的11o

您可以删除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的基本东西。