OpenStruct.new 存储属性,但不检索它



创建一个新的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添加一个别名为ypsych_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这样基本的东西。

相关内容

  • 没有找到相关文章

最新更新