特異クラスを取り出す
今日見つけたなぞのコード。
singleton = class << service; self; end
serviceは任意のオブジェクト。どうもこれで、serviceの特異クラスを取り出しているらしい。
- 取り出したクラスは、クラスなので、「instance_methods」でメソッド一覧を取得したり、「define_method」でメソッドを定義したりできる。
- 「define_method」で定義したメソッドは、serviceでのみ有効になる。(他のserviceと同じクラスのインスタンスには影響しない。)
# テスト用クラス class Kitten def meow( count ) puts "meow!"*count end end mii = Kitten.new kuro = Kitten.new # 特異クラスを取得 new_kitten = class << mii; self ; end # 特異クラスにメソッドを定義 new_kitten.__send__(:define_method, :meow?) { puts "meow?" } # 特異クラスのメソッド一覧を表示 p new_kitten.instance_methods # メソッドの呼び出し mii.meow 3 mii.meow? # miiではmoew?が定義されている。 kuro.meow 2 kuro.meow? # これはエラー
実行結果です。
["instance_variables", "__id__", "to_s", "send", "dup", "private_methods", "=~", "method", "is_a?", "class", "tainted?", "singleton_methods", "object_id", "eql?", "untaint", "instance_of?", "id", "instance_variable_get", "inspect", "instance_eval", "extend", "nil?", "__send__", "frozen?", "taint", "instance_variable_defined?", "public_methods", "hash", "to_a", "clone", "protected_methods", "respond_to?", "freeze", "display", "meow?", "meow", "kind_of?", "==", "instance_variable_set", "type", "===", "equal?", "methods"] meow!meow!meow! meow? meow!meow! .../class.rb:26: undefined method `meow?' for #<Kitten:0x10030d6c> (NoMethodError)
うーん、難しいな。この理解であってるのかな?