2012-11-04 39 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的基本東西。