💨
[Bug #21535] 『メソッドの呼び出し方』によって発生する例外が異なるというバグ報告
[Bug #21535] NoMethodError becomes NameErrorwhen using ... delegation and method call indirection
-
...を引数にしてメソッドを呼び出した場合に『そのメソッドの呼び出し方』によって発生する例外が異なるというバグ報告 - 例えば次のように『存在しないメソッドを呼び出しているメソッド』を呼び出した場合は
NoMethodErrorが発生する
class Test
# 引数を ... で forward する
def foo(...)
nil.bar(...)
end
end
begin
Test.new.foo
rescue => e
pp e
# => #<NoMethodError: undefined method 'bar' for nil>
end
- しかし、次のように『更に別のメソッドを経由して
fooを呼び出す』場合に意図しない例外が発生する- こちらも同様に
NoMethodErrorになってほしいが Ruby 3.4 ではNameErrorになる
- こちらも同様に
class Test
def foo(...)
nil.bar(...)
end
def foo_indirect
foo
end
end
begin
Test.new.foo_indirect
rescue => e
# Ruby 3.3 では NoMethodError が発生するが Ruby 3.4 では NameError になる
pp e
# Ruby 3.3 => #<NoMethodError: undefined method `bar' for nil>
# Ruby 3.4 => #<NameError: undefined local variable or method 'bar' for nil>
end
-
...の引数の forward に関しては他にもいくつか問題があったと思うのでそれ関連ですかねえ - 実際に原因となったコミットが forward 関連の最適化の影響みたい
- ちなみに
...ではなくて*, **, &であれば問題ないので回避したい場合はそちらを利用する手段はあるみたいですね
class Test
def foo(*, **, &)
nil.bar(*, **, &)
end
def foo_indirect
foo
end
end
begin
Test.new.foo_indirect
rescue => e
# Ruby 3.3 では NoMethodError が発生するが Ruby 3.4 では NameError になる
pp e
# Ruby 3.3 => #<NoMethodError: undefined method `bar' for nil>
# Ruby 3.4 => #<NoMethodError: undefined method 'bar' for nil>
end
Discussion