2014-05-24 8 views
5

In Ruby versuche ich zwischen den to_enum und enum_for Methoden zu verstehen. Bevor ich meine Frage stelle, habe ich einen Beispielcode und zwei Beispiele zur Verfügung gestellt, um mit dem Kontext zu helfen.Unterschiede zwischen [1,2,3] .to_enum und [1,2,3] .enum_for in Ruby

Beispielcode:

# 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 

Beispiel # 1:

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

In Beispiel # 1: Aufrufe von group_by auf dem Array [1,2,3], ohne in einem Block verläuft, gibt einen Enumerator mit dem Befehl erzeugten self.enum_for(:group_by_2).

Beispiel # 2

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

In Beispiel # 2, der Enumerator durch Aufrufen der to_enum Methode auf dem Array erzeugt wird [1,2,3]

Frage:

die Enumeratoren Do erzeugt in den Beispielen 1 und 2, verhalten sich in irgendeiner Weise anders? Ich kann von den überprüften Ausgaben sehen, dass sie etwas unterschiedliche Bezeichnungen zeigen, aber ich kann irgendeinen Unterschied im Verhalten der Aufzähler finden.

# 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" 

Antwort

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

--output:-- 

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

Aus der Dokumentation:

to_enum

Erstellt einen neuen Enumerator, die durch Aufruf der Methode auf obj, vorbei an args wenn überhaupt aufzählen wird.

...

enum_for

Erstellt einen neuen Enumerator, die durch Aufruf der Methode auf obj, vorbei an args wenn überhaupt aufzählen wird.

Ruby ist eine Sprache, die oft Methodennamen hat, die Synonyme sind.

Followup Frage:

bedeutet das Symbol in dem Befehl [1,2,3] .to_enum (: foo) dienen einem Zweck, andere als Ersatz: jede mit: foo in dem Ausgangs ?

Ja. Standardmäßig bindet Ruby den Enumerator an die each() -Methode des Empfängers an.Einige Klassen keine each() Methode haben, zum Beispiel String:

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() erlaubt es, die Methode geben Sie den Enumerator möchten verwenden:

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

--output:-- 
hello 

Nun nehmen wir Sie Haben Sie das Array [1, 2, 3], und Sie möchten einen Enumerator für Ihr Array erstellen. Ein Array hat eine each() -Methode, aber anstatt einen enumerator mit jedem() zu erstellen, der jedes der Elemente im Array zurückgibt, endet es; Sie möchten einen Enumerator erstellen, der am Anfang des Arrays beginnt, sobald das Ende erreicht ist?

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

@ 7stud danke. Ich wollte nur sicherstellen, dass ich nichts verpasst habe. – amorphid

+2

@amorphid, Die Ruby-Dokumentation war ziemlich gut zu sagen: "Diese Methode ist ein Synonym für Methode A. Siehe Beschreibung für Methode A." Ich würde diese Empfehlung lieber als eine doppelte Beschreibung sehen. – 7stud

+0

Ich lese gerade dein Beispiel neu und habe gerade erkannt, dass man auch '[1,2,3] .to_enum (: foo)' machen kann, was '# ' zurückgibt . Hätte ich es gemerkt, wäre meine Frage einfach => Hat das Symbol im Befehl '[1,2,3] .to_enum (: foo)' einen anderen Zweck als den Ersatz 'jedes' mit ': foo' in der Ausgabe? Die [Docs für die Enumerator-Klasse] (http://www.ruby-doc.org/core-2.1.2/Enumerator.html) sagen nichts darüber, zumindest nicht, dass ich sehen kann. – amorphid