【一人 bugs.ruby Advent Calendar 2021】[Bug #17571] prependしたArray#[] が反映されない【16日目】
一人 bugs.ruby Advent Calendar 2021 16日目の記事になります。
今日はArray
に prepend
してる #[]
が呼び出されないバグの話です。
[Bug #17571] prependしたArray#[] が反映されない
以下のように Array
に prepend
してる #[]
が呼び出されないことがあるというバグ報告です。
module TestMod def [](*) :called end end Array.prepend TestMod # 引数がある場合 # これは Array#[] が呼ばれる p [1, 2, 3][1] # => 2 # 引数がない場合 # これは TestMod#[] が呼ばれる p [1, 2, 3][] # => :called # Method オブジェクトは TestMod を指している p [1, 2, 3].method(:[]) # => #<Method: Array(TestMod)#[](*) /tmp/vud3mdg/27:2>
[1, 2, 3][1]
が意図していない挙動になっています。
これは Array#[]
を事前にメソッドキャッシュしており、そちらを優先して呼び出しているのが原因らしいです。
なので prepend
しているメソッドは呼ばれなくなっていた。
更に引数がない場合は Array#[]
とシグネチャが異なるのでキャッシュされたメソッドではなくて prepend
されたメソッドを呼び出しているので意図する挙動になっているようです。
これは Ruby 3.0 に存在しているバグで Ruby 3.1 では修正されています。