在创建一个新的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添加一个别名为Kernelpsych_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 = 1111里面。
您可以这样删除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这样基本的东西。

09-25 20:37