2014-05-24 36 views
5

Ruby'de to_enum ve enum_for yöntemleri arasında anlamaya çalışıyorum. Sorumu almadan önce, bazı örnek kodlar ve içerik/içerik için iki örnek verdim.Ruby'de [1,2,3] .to_enum ve [1,2,3] .enum_for arasındaki farklar

örnek kod:

# replicates group_by method on Array class 
class Array 
    def group_by2(&input_block) 
    return self.enum_for(:group_by2) unless block_given? 
    hash = Hash.new {|h, k| h[k] = [] } 
    self.each { |e| hash[ input_block.call(e) ] << e } 
    hash 
    end 
end 

Örnek 1: Örnek # olarak

irb (main)> puts [1,2,3].group_by2.inspect 
=> #<Enumerator: [1, 2, 3]:group_by2> 

1: Bir blok içinde geçmeden, dizi [1,2,3] ile group_by çağırma komutu oluşturulacak bir sýralayýcý döndürür self.enum_for(:group_by_2).

Örnek 2 2., Numaralayıcı dizi to_enum yöntemi çağrılarak oluşturulur örnekte

irb (main)> puts [1,2,3].to_enum.inspect 
=> #<Enumerator: [1, 2, 3]:each> 

[1,2,3]

Soru:

sıralayıcısını fazlası örnek 1 'de üretir ve 2, herhangi bir şekilde farklı davranır mı? İncelenen çıktılardan biraz farklı etiketler gösterdiklerini görebiliyorum, ancak sayımcıların davranışlarında herhangi bir fark bulabilirim. Dokümanlar

# Output for example #1 
#<Enumerator: [1, 2, 3]:each> # label reads ":each" 

# Output for example #2 
#<Enumerator: [1, 2, 3]:group_by2> # label reads ":group_by2" 

cevap

10
p [1, 2, 3].to_enum 
p [1, 2, 3].enum_for 

--output:-- 

#<Enumerator: [1, 2, 3]:each> 
#<Enumerator: [1, 2, 3]:each> 

:

to_enum

varsa args geçerek obj üzerinde yöntemini çağırarak numaralandırma yeni Numaralandırıcıyı oluşturur.

...

enum_for

varsa args geçerek obj üzerinde yöntemini çağırarak numaralandırma yeni Numaralandırıcıyı oluşturur.

yakut genellikle eş olan yöntem adları olan bir dildir.

İzleyen soru:

komut sembolü mı [1,2,3] .to_enum (: ece) değiştirilmesi dışında bir amaca hizmet: çıkış ece'nin: her biri ?

Evet. Varsayılan olarak ruby, numaralandırıcıyı alıcının her() yöntemine kancalar.Kullanmak numaralandırıcıyı istiyorum

str = "hello\world" 
e = str.to_enum 
puts e.next 

--output:-- 
1.rb:3:in `next': undefined method `each' for "helloworld":String (NoMethodError) 
    from 1.rb:3:in `<main> 

to_enum() Eğer yöntemini belirlemenizi sağlar: Bazı sınıflar örnek dize, bir her() yöntemini yok

str = "hello\nworld" 
e = str.to_enum(:each_line) 
puts e.next 

--output:-- 
hello 

Şimdi size varsayalım dizisi [1, 2, 3] olsun ve diziniz için bir numaralandırıcı oluşturmak istiyorsunuz. Bir dizinin her bir() yöntemi vardır, ancak her bir() öğesiyle bir numaralayıcı oluşturmak yerine, dizideki öğelerin her birini döndürür, sonra sonlandırır; Sonuna ulaştıktan sonra dizinin başlangıcından başlayarak bir sayım oluşturmak istersiniz? 7stud sayesinde @

e = [1, 2, 3].to_enum(:cycle) 

10.times do 
    puts e.next() 
end 

--output:-- 
1 
2 
3 
1 
2 
3 
1 
2 
3 
1 
+0

. Sadece bir şey kaçırmadığımdan emin olmak istedim. – amorphid

+2

@amorphid, ruby ​​docs, "Bu yöntem, A yöntemi eşanlamlısıdır." Bu başvuruyu yinelenen bir açıklamadan daha iyi görmeyi tercih ederim. – 7stud

+0

Örneğini tekrar okudum, ve şimdi de birinin [1,2,3] .to_enum (: foo) 'nu yapabildiğini fark etti, ki bu da # # Enumerator: [1, 2, 3] 'i döndürüyor: foo>' . Bunu fark etmiş olsaydım, sorum şu olurdu: => [1,2,3] .to_enum (: foo) komutundaki sembol, ':' ile ': foo' yerine başka bir amaca hizmet eder mi? çıktıda? [Enumerator sınıfı için dokümanlar] (http://www.ruby-doc.org/core-2.1.2/Enumerator.html) bunun hakkında hiçbir şey söylemiyor, en azından göremiyorum. – amorphid