2012-01-30 21 views
10

singleton_class.class_eval. Tass, bu örnekte, singleton_class'ın her yeni nesne için farklı bir object_id döndüreceğini, çünkü singleton_class'ın yalnızca bir Object'e ait olduğunu yanıtladı. Ama IRB gösterileriyakut self.class.class_eval veya

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

İşlevsel bir fark bulamıyorum, ama bence bir tane olmalı. –

+2

@JakubHampl, fark buldum gibi görünüyor) –

+1

@AlexKliuchnikau Birisi biliyordum. + 1 sana! –

cevap

10

bu T sınıfların örnekleri arasındaki farklar yöntemi arama algoritmasında geçerli: yöntem her zaman tekil sınıfının (ve onun birimleri) içinde aranır ve burada bulunmazsa sadece, eğer sınıfta aranır.

biz biz sınıfta T ikinci uygulanması için aynı şeyi yaparken daha farklı bir sonuç alacak başlatmasından sonra sınıfın T ilk uygulamasına yöntem test eklerseniz Bu demek:

# 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

Yanıt için teşekkürler! şimdi fark görüyorum) – Fivell

+0

Pratik bir bakış açısından, diğerini ne zaman yaparsınız? – Claw

+0

@Claw, yukarıdaki metodlar sadece test örneklerini merak ediyor, ben gerçek sınıfın başlatıcısı olarak böyle bir şey yazmam. Genel olarak: * sınıfı * yöntemini, yöntemi * tüm * örneklerine eklemeniz ve yöntemi * tekil sınıfına * eklemeniz gerekir. Örnek 2'de, her * yöntem örneğinin * (*) * tekil sınıfı * yöntemine yöntem eklenir (başlatıcıda) - bu pratik değildir, bu tür durumlarda * sınıf * yöntemini ekleyin. –

7

singleton_class sonraki sana o nesneye özgü olan Class verir. self.class, size bu Class paylaşımının tüm nesnelerini sunar. Bir singleton_class tek Object ait olduğu için Yukarıdaki örnekte

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 

Example, singleton_class, her bir yeni nesne için farklı object_id döndürür. self.class aynı şekilde döner çünkü self.class her seferinde aynı Class işaret eder.

+2

Bu, doğrudan dokümanlardan hemen sonra geliyor. Ama bu sorunun cevabı değil. Yukarıdaki iki kod, aslında yukarıdaki kodda ne gibi bir fark yaratıyor? –

+1

OP gibi görünüyor, sınıf ve singleton sınıfı arasındaki fark nedir, ancak program yürütme açısından sağlanan bu iki örnek arasındaki fark nedir. Her iki durumda da 'T' örnekleri 'test' yöntemiyle örneğe sahip olacak ve nasıl farklılar? –

+0

Cevabınız için teşekkürler, Alex, ben, – Fivell