2016-03-30 19 views
0

Ich habe eine Zeichenfolge:Enumerator zu verschiedenen Klassenwechsel

bottom_line = "some text" 

Wenn ich einen Enumerator von ihm mit enum_for erstellen, und versuchen each darauf zu nennen, erhalte ich eine Fehlermeldung:

z = bottom_line.enum_for 
z.each {|item| item.scan(/some_regex/)} 
# => undefined method `each' for #<String:0x00000001f65350> 

Was geht hier vor sich?

Wenn ich enum_for Kette mit dem Verfahren alle in einer Zeile, es funktioniert:

z = bottom_line.enum_for(:scan, /some_regex/) 
+0

Vielen Dank für die klare Erklärung Cary - ich in der Dokumentation hatte versucht, Blick vor aber war Blick auf der Enumerator Dokumentation und I didn‘ t realisieren, dass es die Methode #each an die Klasse des zugrunde liegenden Objekts übergeben hat, String in diesem Fall –

Antwort

0

z.each bewirkt, dass das Verfahren Enumerator#each zu z gesendet werden. Enumerator#each erhält die Klasse von enum_for Empfänger (bottom_line), die String ist. Es scheint dann die Methode String#each aufzurufen. Eine solche Instanzmethode wird in der Klasse String nicht gefunden. Daher wird die Ausnahme ausgelöst, die Sie erhalten haben.

2

Bevor Sie fragen, sollten Sie sich die Dokumentation unter Object#enum_for ansehen.

Object#enum_for akzeptiert 1+ Parameter: die Methode, die aufgerufen wird, wenn die Enumeration tatsächlich aufgerufen wird (standardmäßig :each) und die Argumente, die an diese Methode übergeben werden.

Das heißt,

z = bottom_line.enum_for 

ist ein absolutes entspricht:

z = bottom_line.enum_for(:each) 

während die inlined Version

ist
z = bottom_line.enum_for(:scan) 

warum sollte man erwarten, dass sie die gleiche Art und Weise verhalten? Um die gleiche Funktionalität zu erreichen könnte man explizit die Methode in dem Aufruf von enum_for angeben:

z = bottom_line.enum_for :scan 
z.each(/some_regexp/) { |item| puts item } 
+0

upvoted für * Blick auf die Dokumentation vor der Anfrage * Hinweis – joanbm