4

新しいRubyOpenStructオブジェクトを作成した後、属性を保存することはできますが、属性を取得することはできません(空白行が表示され、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]

誰かが何が起こっているのか考えていますか?

4

1 に答える 1

5

どこかPsychでYAMLのものを引き込んでいます。にエイリアスされるメソッドを追加するためのPsychパッチKernel。したがって、すべてにメソッドが定義されています。psych_yyy

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

AFAIK、OpenStructはmethod_missing、内部ハッシュを使用してアクセサーメソッドとミューテーターメソッドを生成します。しかし、yカーネルへのその「フレンドリーな」パッチはすでに存在するため、Psychの魔法が邪魔をしているため、OpenStructの魔法はメソッドを処理できませんy。ミューテーター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

于 2012-11-04T18:27:50.253 に答える