2010-05-02 11 views
7

Il seguente frammento di codice funziona bene in 1.8.7 su Mac OS X, ma non in 1.8.6 su Ubuntu. Perché? C'è una soluzione?Perché 6.times.map funziona in ruby ​​1.8.7 ma non 1.8.6

Lavori in 1.8.7:

$ ruby --version 
ruby 1.8.7 (2009-06-08 patchlevel 173) [universal-darwin10.0] 
ltredgate15:eegl leem$ irb 
>> 6.times.map {'foo'} 
=> ["foo", "foo", "foo", "foo", "foo", "foo"] 
>> 

ma non in 1.8.6:

# ruby --version 
ruby 1.8.6 (2008-08-11 patchlevel 287) [i686-linux] 
Ruby Enterprise Edition 20090610 
# irb 
irb(main):001:0> 6.times.map {'foo'} 
LocalJumpError: no block given 
     from (irb):1:in `times' 
     from (irb):1 
irb(main):002:0> 

Perché c'è una differenza? Qual è la soluzione alternativa per 1.8.6?

risposta

16

In 1.8.7+ i metodi di iterazione come times restituiscono un enumeratore se vengono chiamati senza blocco. In 1.8.6 si deve fare

require 'enumerator' 
6.enum_for(:times).map {...} 

O per questo specifico caso d'uso si può semplicemente fare (0...6).map {...}

+2

Oppure 'richiedere' backport'' ... –

+0

Ora è possibile richiedere solo i backport necessari. In questo caso ... 'richiede 'backport/1.8.7/integer/times'' –

1

perché 1.8.6 #times rendimenti sul blocco specificato, mentre 1.8.7 restituisce un oggetto Enumerator puoi tenerti in giro e implementare Enumerable.

6

In Ruby 1.9, la libreria è stata modificata in modo che le funzioni che eseguivano l'iterazione restituivano un oggetto Enumerator se venivano richiamati senza un blocco. È stata modificata anche un'intera serie di altre funzionalità linguistiche ed era ampiamente noto che la compatibilità sarebbe stata interrotta tra Ruby 1.8.xe Ruby 1.9 nell'interesse di migliorare la lingua nel suo complesso. La maggior parte delle persone non ha trovato questo troppo angosciante.

Il team di sviluppo di Ruby ha deciso che Ruby 1.8.7 dovrebbe essere una versione di transizione che aggiunge alcune delle funzionalità di libreria introdotte da Ruby 1.9. Hanno preso molte critiche per la decisione, e molti utenti di Ruby aziendali sono rimasti (e molti ancora rimangono) su Rails su Ruby 1.8.6, perché ritengono che le modifiche introdotte 1.8.7 siano troppo grandi e troppo rischiose. Tuttavia, rimane 1.8.7 e le funzioni di iterazione restituiscono Enumerator è una delle funzionalità incorporate.

È questa funzione di migrazione che si vede in 1.8.7, che non è presente in 1.8.6.

La risposta di sepp2k offre una buona soluzione. Non c'è molto per me da aggiungere su quel conteggio.

+0

grazie per le informazioni di base, davvero buone da sapere. – Lee

+0

Vorrei aggiungere che 1.8.7 è per lo più compatibile (e quando non lo è, 1.9 non lo sarà). Controlla questa domanda http://stackoverflow.com/questions/2544185/upgrade-ruby-projects-from-1-8-6-to-1-8-7/2545416#2545416 –

1

Ruby 1.8.7 introduce many changes. Se vuoi usarli in Ruby 1.8.6, semplicemente

require 'backports' 

Questo è tutto. Questo ti dà molti metodi di 1.9.1 e l'imminente 1.9.2, sebbene sia possibile fare il require 'backports/1.8.7' solo per le modifiche di 1.8.7, o anche solo i backport necessari, ad es. require 'backports/1.8.7/integer/times'

Problemi correlati