質問
prag daveによる最初のルビーメタプログラミングスクリーンキャストを見ていました。ある時点で、インスタンス変数にメソッドを追加するとルビーは「ゴーストクラス」を導入すると述べました。 i。
animal = "cat"
def animal.speak
puts "hola"
end
animal.speak # => hola
animal.class # => String
dog = "dog"
dog.speak # Undefined method `speak' for "dog":String
String.send :speak # NoMethodError: undefined method `speak' for String:Class
animal.send :speak # hola
実際に話すメソッドストアはどこですか? 非表示のプロキシクラスの場合、そのプロキシクラスにアクセスするにはどうすればよいですか
解決
メソッド speak
は、「不可視プロキシクラス」と呼ばれるメタクラス(固有クラスとも呼ばれます)に格納されます。 Rubyでは、インスタンス変数にはメソッドを保存する場所がありません。インスタンス変数とそのクラスのみを保存できます。したがって、インスタンスにメソッドを追加すると、メタクラスが作成され、そのクラスチェーンに挿入されます。内部の理解を深めるために、この記事のKlank Boom Klang。
メタクラスを取得するには、次の操作を実行できます。
animal = "cat"
def animal.speak
puts "hola"
end
animal.speak # => hola
animal.class # => String
metaclass = class << animal; self; end
metaclass.inspect # => #<Class:#<String:0x2c9c460>>
metaclass.instance_methods.index 'speak' # => 102
metaclass.class # => Class
他のヒント
一部のpplは「シングルトンクラス」と呼びます
singleton_class = class << animal; self; end
実際、このシングルトンクラスはどのクラスのクラスメソッドのホストでもあります。まず、クラスメソッド 'hi'と 'bye'でクラスFooを定義することにより、この例をチェックしてください:
class Foo
def self.hi ; p "hi" ; end
def self.bye ; p "bye" ; end
end
Foo.singleton_methods #=> ["hi","bye"]
次に、シングルトンクラスを返すメソッドを定義します。
class Object
def singleton_class
class << self
self
end
end
end
今これを試してください:
Foo.singleton_methods #=> ["bye", "hi"]
Foo.singleton_class.instance_methods(false) #=> ["bye", "hi"]
所属していません StackOverflow