Illustriamo il punto con un esempio:
results = []
(1..3).each do |i|
results << lambda { i }
end
p results.map(&:call) # => [1,2,3]
fresco, questo è ciò che ci si aspettava. Ora verifica quanto segue:
results = []
for i in 1..3
results << lambda { i }
end
p results.map(&:call) # => [3,3,3]
Huh, che sta succedendo? Credimi, questi tipi di bug sono cattivi da rintracciare. Gli sviluppatori Python o JS sapranno cosa intendo :)
Questo solo è un motivo per me per evitare questi cicli come la peste, anche se ci sono più buoni argomenti a favore di questa posizione. Come Ben ha sottolineato correttamente, l'utilizzo del metodo corretto da Enumerable
porta quasi sempre a un codice migliore rispetto all'utilizzo di semplici vecchi, imperativi cicli for
o fancier Enumerable#each
. Ad esempio, l'esempio precedente potrebbe anche essere conciso scritto come
lambdas = 1.upto(3).map { |i| lambda { i } }
p lambdas.map(&:call)
espando la domanda: quale altro in Ruby vediamo cosa fare apears/blocco delimitatori finali, ma non c'è in realtà alcuna portata dentro? Qualcos'altro oltre a ... do ... fine?
Ogni singolo uno dei costrutti di loop può essere utilizzato in questo modo:
while true do
#...
end
until false do
# ...
end
D'altra parte, possiamo scrivere ogni uno di questi senza la do
(che ovviamente è preferibile):
for i in 1..3
end
while true
end
until false
end
Un'altra espansione della domanda, c'è un modo per scrivere per ciclo con parentesi graffe {} blocco
No, non c'è. Si noti inoltre che il termine "blocco" ha un significato speciale in Ruby.
Solo una nota a margine (ho già detto qualcosa del genere in un altro commento): il problema con 'for' non è solo che differisce in modo sottile dagli altri costrutti usando' do/end', ma anche che può essere usato solo per una sola ragione: attraversare un numero enumerabile. Spesso, i costrutti dalla programmazione funzionale come 'select' o' map' sono molto più adatti per esprimere un problema piuttosto che un semplice ciclo vecchio, ereditato direttamente da C. –
E viceversa: dai esempi reali di dove pensi che sia necessario un ciclo 'for' e ti offriamo un'alternativa migliore? :) Altrimenti penso che questa domanda sia solo un duplicato di http://stackoverflow.com/questions/3294509/for-vs-each-in-ruby –
E per quanto riguarda le prestazioni? Non è semplice per più veloce di entrare in una chiusura? E se dovessi _want_ definire le variabili locali in ciclo for per un uso successivo :)? (Solo pensieri rapidi su ciò che potrebbe essere buono :) –