レシーバーのクラスでfoo
クラス メソッドを呼び出すmethod を使用してモジュールを作成しています。bar
私の現在のアプローチはself.class.bar
、クラスメソッドが「実際の」クラスではなくインスタンスクラスで定義されていない限り、正常に機能する を使用することです。
module M
def foo
self.class.bar
end
end
obj = Object.new
class << obj
include M
def self.bar
42
end
end
obj.foo # => NoMethodError: undefined method `bar' for Object:Class
obj.class
シングルトン クラスを返さないため、これは理にかなっています。代わりに使用できobj.singleton_class
、すべてがスムーズに実行されます。
module M
def foo
self.singleton_class.bar
end
end
obj = Object.new
class << obj
include M
def self.bar
42
end
end
obj.foo # => 42
上記と同じ理由で、メソッドがシングルトン クラスで定義されている場合のみ。さらに悪いことに、レシーバーごとに新しいシングルトン クラスが作成されます。これは、かなりの量のオブジェクトになる可能性があるため、避けたいものです。代わりに、オブジェクトのシングルトン クラスが既に定義されている場合にのみobj.has_singleton_class ? obj.singleton_class : obj.class
、つまり type の何かを取得する方法が必要です。ただし、このチェックを実行する方法が見つかりませんでした。