2012-01-22 11 views
11

Ruby'de meta programlamayı öğreniyorum ve metod_missing ve define_method ile eksik yöntemleri tanımlamaya çalışıyorum. Beklenmedik davranışlar alıyorum ve bunu açıklayabilir mi diye merak ediyorum. İşte benim sınıftır: ArtıkRuby: neden to_ary'yi çağırıyor?

class X 
    def method_missing(m, *args, &block) 
    puts "method #{m} not found. Defining it." 
    self.class.send :define_method, m do 
     puts "hi from method #{m}" 
    end 
    puts "defined method #{m}" 
    end 
end 

bu kod: neden Yakut çağırıyor: ben alamadım ne

method some_method not found. Defining it. 
defined method some_method 

hi from method some_method 

method to_ary not found. Defining it. 
defined method to_ary 
#<X:0x007fcbc38e5030> 

son parçasıdır:

x = X.new 

x.some_method 
puts 
x.some_method 
puts 
puts x 

çıkışını üretir Bir çağrıya to_ary koyar? Ruby neden nesneyi yazdırmak için bir diziye dönüştürmeyi denedi?

Etrafa Googled ve ettik

bulundu bu ilgili bağlantılar:

Bunlar da method_missing ve to_ary Sorunlar hakkında konuşmak değil, spesifik olarak koyar to_ary çağırır neden .

Ayrıca bir to_s tanımladığımda, davranışın değişmediğinden de söz etmeliyim, ör.

def to_s 
    "I'm an instance of X" 
end 

"koyar x" çıkış

o zaman:

method to_ary not found. Defining it. 
defined method to_ary 
I'm an instance of X 

cevap

14

puts$stdout.puts eşanlamlıdır. $ Stdout'u bir IO sınıf, yani IO.puts belgelerine bakın:

IO # baskı gibi ios verilen nesneleri yazar. ayırıcısını (genellikle bir satırsonu) bir satırsonu dizisi ile bitmemiş olanlardan sonra yazar. Dizi argümanı ile çağrılırsa, her öğesini yeni bir satıra yazar.

Bu, puts yönteminin birkaç satırlık çıktı yazmak için kullanılması anlamına gelir. Bu nedenle, bir nesnede to_ary yöntemini çağırmaya çalışır ve to_ary tanımlanmışsa, Array döndürülen öğenin her bir öğesini yeni bir satıra yazdırır,yöntemini çağırır.

to_ary iç kullanım gerçekten iyi (onun Yakut Programlama Dili kitapta Matz noktalarını bunu) Ruby belgelerinde belgelenmiştir.

Yöntemler print ve p diğer yandan to_ary, yalnızca to_s numaralı telefonu arayınız.

Sidenote: İlginç, to_ary gerçek Array nesneyi değil, each yöntemini veya başka bir şey tanımlayan bir nesne döndürmesi gerekir:

class Test 
    def to_ary 
    10.downto(1) 
    end 
end 

puts Test.new 

#TypeError: can't convert Test to Array (Test#to_ary gives Enumerator) 
#  from (irb):28:in `puts' 
#  from (irb):28:in `puts' 
#  from (irb):28 
+0

teşekkürler. Bence özünün "to_ary iç kullanım gerçekten Ruby belgelerinde iyi belgelenmemiş" olduğunu düşünüyorum. :) Ben sadece IO.puts belgelerini okudum, açık bir şekilde to_ary'den bahsetmiyorlar, bence bu daha açık olmalıydı. "Ruby Programlama Dili" kitabına işaret ettiğiniz için teşekkür ederiz. –