and*_*vom 4 ruby null openstruct
在创建一个新的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
Run Code Online (Sandbox Code Playgroud)
如果我尝试使用不同的名称存储其他属性,一切都按预期工作.这个问题似乎只有在我存储一个名为的属性时才会发生y.我使用以下版本:
ruby 1.9.2p320 (2012-04-20 revision 35421) [i686-linux]
有没有人知道发生了什么?
某些地方正在吸引PsychYAML的东西.心理补丁Kernel添加一个psych_y别名的方法y.所以,一切都有y定义的方法:
> o = OpenStruct.new
> o.method(:y)
=> #<Method: OpenStruct(Kernel)#psych_y>
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
你可以删除该方法,Kernel并希望没有任何东西取决于这个愚蠢的y别名:
> Kernel.send(:undef_method, :y)
> o = OpenStruct.new
> o.y = 11
> o.y
=> 11
Run Code Online (Sandbox Code Playgroud)
或者您可以将其从OpenStruct以下位置删除:
> OpenStruct.send(:undef_method, :y)
> o = OpenStruct.new
> o.y = 11
> o.y
=> 11
Run Code Online (Sandbox Code Playgroud)
这就是为什么许多人不喜欢猴子修补,特别是猴子修补一些基本的东西Kernel.