🔥
[Bug #20620] 自身を extend したときの .singleton_method に関するバグ報告
[Bug #20620] singleton_method undefined for module using "extend self"
- 以下のように
extend self
したときにself
のメソッドが.singleton_method
で取得することができないバグ報告 - 通常は以下のようにクラスメソッドが定義されている場合は
.singleton_method
でクラスメソッドのオブジェクトを取得することができます
class Klass
def self.foo
end
end
p Klass.singleton_methods
# => [:foo]
p Klass.singleton_method(:foo)
# => #<Method: Klass.foo() singleton_method.rb:2>
- しかし、以下のように自身を
extend
した場合にうまく取得することができないとのこと
module ExtendSelf
extend self
def foo
end
end
p ExtendSelf.singleton_methods
# => [:foo]
# error: `singleton_method': undefined singleton method `foo' for `ExtendSelf' (NameError)
p ExtendSelf.singleton_method(:foo)
- これなんですが
.singleton_method
は『特異クラスに定義されているメソッドを返す』ことになります - なので前者の
Klass.singleton_method(:foo)
は.foo
が特異クラスにメソッドが定義されているので問題ありません - しかし、後者の
ExtendSelf.singleton_method(:foo)
は.foo
が特異クラスではなくて『継承リストのモジュール内で定義されている』ので厳密にいうと特異メソッドとしては扱われない感じですかね - また
.singleton_methods
に関しては引数がない場合は『継承した特異メソッドも含む』になるのでExtendSelf.singleton_methods
に:foo
が含まれます - ただし
.singleton_methods(false)
にすることで『継承した特異メソッドを含まない』になり:foo
が含まれなくなります
module ExtendSelf
extend self
def foo
end
end
# こっちは継承した特異メソッドを含む
p ExtendSelf.singleton_methods
# => [:foo]
# こっちは継承した特異メソッドを含まない
p ExtendSelf.singleton_methods(false)
# => []
- なのでこれ自体はバグではないとのこと
Discussion