😺
[Bug #21267] Class#allocate に関するバグ報告
[Bug #21267] respond_to check in Class#allocate is inconsistent
-
Class#allocateではrb_obj_respond_to(klass, rb_intern("allocate"))のようなチェックを行っており#respond_to?で.allocateが呼び出せないような状況であればエラーになるようになっている- 要はクラス側で
.allocateがprivate等で呼び出せない状況になっている場合は親クラスのメソッドであるClass#allocateが失敗するようになっている
- 要はクラス側で
- これは以下のように
Class#allocateを#bind_call等からの呼び出しを禁止しているのが理由みたいです
class X
class <<self
undef_method :allocate
end
end
# Class#allocate を直接呼び出すようなコード
# error: calling X.allocate is prohibited (TypeError)
Class.instance_method(:allocate).bind_call(X)
- 意図的にこういう呼び出しを禁止しているのですが次のようにサブクラスで
Class#allocateを再定義するとこれが突破されてしまうというバグ報告
class X
class <<self
undef_method :allocate
end
end
class Y < X
def self.allocate
end
end
# no error
# Y.allocate が定義されているので `respond_to?` で呼び出せる判定になる
# しかし、実際には Class#allocate が呼び出されてしまう
Class.instance_method(:allocate).bind_call(Y)
- チケットの内容としてはこのチェック自体を削除したいみたいですね
- モチベーションとしてはこのチェックがパフォーマンスに影響があるので削除したいみたい
- これなんですが最終的には開発版の Ruby 3.5-dev では『
rb_obj_respond_to(klass, rb_intern("allocate"))のチェック自体を削除する』という対応になりました
class X
class <<self
undef_method :allocate
end
end
Class.instance_method(:allocate).bind_call(X)
# Ruby 3.4 => error: calling X.allocate is prohibited (TypeError)
# Ruby 3.5 => no error
Discussion