2012-01-30 3 views
10

singleton_class.class_eval。 この例では、singleton_classが1つのオブジェクトにのみ属しているため、singleton_classは新しいオブジェクトごとに異なるobject_idを返します。しかし、IRBは次を示しルビーself.class.class_evalまたは

1.9.2p180 :001 > class T 
1.9.2p180 :002?> 
1.9.2p180 :003 >  def initialize 
1.9.2p180 :004?>  singleton_class.class_eval do 
1.9.2p180 :005 >    def test 
1.9.2p180 :006?>     return self.class.object_id 
1.9.2p180 :007?>    end 
1.9.2p180 :008?>  end 
1.9.2p180 :009?>  end 
1.9.2p180 :010?> 
1.9.2p180 :011 >  end 
=> nil 
1.9.2p180 :012 > t = T.new 
=> #<T:0x00000100ae9cb8> 
1.9.2p180 :013 > t1 = T.new 
=> #<T:0x00000100ad7ef0> 
1.9.2p180 :014 > t1.test == t.test 
=> true 
1.9.2p180 :015 > t1.test 
=> 2153233300 
1.9.2p180 :016 > t.test 
=> 2153233300 
1.9.2p180 :017 > 
+1

私は機能的な違いを見つけることはできませんが、私はそこにあるべきだと思います。 –

+2

@JakubHampl、違いを見つけたように見えます) –

+1

@AlexKliuchnikau誰かが分かっていました。あなたに+1! –

答えて

10

これらTのクラスのインスタンス間の違いは、メソッド探索アルゴリズムである:メソッドは常にシングルトンクラス(およびそのモジュール)で検索され、それがここで見つからなかった場合にのみ、それがクラスに検索されます

これは、我々が初期化後クラスTの最初の実装にメソッドtestを追加した場合、我々はクラスTの第2の実施のために同じことをしたときとは異なる結果が得られます意味:

# First example 
class T 
    def initialize 
    self.class.class_eval do 
     def test 
     return self.class.object_id 
     end 
    end 
    end 
end 

t = T.new 

class T 
    def test 
    'overriden' 
    end 
end 

puts t.test # => 'overriden' 

class T 
    def initialize 
    singleton_class.class_eval do 
     def test 
     return self.class.object_id 
     end 
    end 
    end 
end 

t = T.new 

class T 
    def test 
    'overriden' 
    end 
end 

puts t.test # => 77697390 
+0

お返事ありがとうございます!今私は違いを参照してください) – Fivell

+0

実用的な観点から、あなたは他のものを1つをやりますか? – Claw

+0

@Claw、上記のメソッドは興味深いテストサンプルです。私はこれを実際のクラスのイニシャライザに書きません。一般的には、メソッドをクラスのすべての*インスタンスに追加する必要がある場合は*クラス*にメソッドを追加し、クラスの*単一インスタンスにメソッドを追加する必要がある場合は*シングルトンクラス*にメソッドを追加します。例2では、​​OPは*メソッドインスタンスの*シングルトンクラス*にメソッドを追加します(イニシャライザではこれは実用的ではありません)。 –

7

singleton_classは、そのオブジェクトに固有であるあなたにClassを与えます。 self.classは、そのすべてのオブジェクトがClassであることを示すクラスを提供します。上記の例でExample

foobar = Array.new 

# this defines a method on the singleton class 
def foobar.size 
    "Hello World!" 
end 

foobar.size # => "Hello World!" 
foobar.class # => Array 

bizbat = Array.new 
bizbat.size # => 0 

singleton_classが一つだけObjectに属しているため、singleton_classは、それぞれの新しいオブジェクトの異なるobject_idを返します。 self.classは、self.classが毎回同じClassを指しているため同じ結果を返します。

+2

これは、ドキュメントからほとんど直接的に従います。しかし、それは質問に対する答えではありません。上記の2つのアプローチは実際にどのような違いがありますか? –

+1

OPのように、クラスとシングルトンクラスの違いは何ではないかと思われますが、彼はプログラム実行の観点から彼らが提供した2つの例の違いは何ですか?どちらの場合も 'T'のインスタンスは' test'メソッドのインスタンスを持ちますが、どう違いますか? –

+0

レスポンスありがとう、アレックス、あなたが言及したdiffrerenceを理解したいと思う – Fivell