2012-03-14 14 views
5

Sto scrivendo una gemma Ruby usando la sintassi {key: 'value'} per gli hash nel mio codice. I miei test passano tutti in 1.9.x, ma io (comprensibilmente) ottengo syntax error, unexpected ':', expecting ')' in 1.8.7.Supporto della sintassi hash di Ruby 1.9 in Ruby 1.8

Esiste una best practice per supportare 1.8.x? Devo riscrivere il codice usando il nostro vecchio amico => oppure esiste una strategia migliore?

+1

Ruby 1.8 sta per svanire presto. Non hai bisogno di supporto per questo. – sawa

+3

È un'opinione popolare? Sto certamente cercando input su ciò che gli altri autori di Gem stanno facendo. So che c'è una grande spinta all'interno della comunità Ruby per portare tutti sul treno 1.9. Personalmente non mi dispiace lasciare 1.8 dietro. – JackCA

risposta

16

Penso che tu sia sfortunato, se vuoi supportare 1.8 allora devi usare =>. Come al solito, 'da notare che è necessario utilizzare => in alcuni casi in 1.9:

  1. Se la chiave non è un simbolo. Ricorda che qualsiasi oggetto (simboli, stringhe, classi, float, ...) può essere una chiave in un Ruby Hash.
  2. Se è necessario un simbolo che si desidera citare: :'this.that'.
  3. Se si utilizza MongoDB per quasi tutto ciò che verrà utilizzato come :$set => hash ma $set: hash è un errore di sintassi.

Torna alla programmazione programmata regolarmente.

Perché dico che sei sfortunato? Le sintassi Hash letterali (entrambe) sono cablate nel parser e non penso che avrai molta fortuna nell'applicare il parser alla tua gemma. Ruby 1.8.7's parse.y ha questo da dire:

assoc : arg_value tASSOC arg_value 
      { 
       $$ = list_append(NEW_LIST($1), $3); 
      } 
     ; 

e tASSOC è => letterali in modo hash sono hard-wired per utilizzare =>. 1.9.3's dice questo:

assoc : arg_value tASSOC arg_value 
      { 
      /*%%%*/ 
       $$ = list_append(NEW_LIST($1), $3); 
      /*% 
       $$ = dispatch2(assoc_new, $1, $3); 
      %*/ 
      } 
     | tLABEL arg_value 
      { 
      /*%%%*/ 
       $$ = list_append(NEW_LIST(NEW_LIT(ID2SYM($1))), $2); 
      /*% 
       $$ = dispatch2(assoc_new, $1, $2); 
      %*/ 
      } 
     ; 

Abbiamo la sintassi grasso-freccia di nuovo (arg_value tASSOC arg_value) e lo stile JavaScript (tLABEL arg_value); AFAIK, tLABEL è anche la fonte delle restrizioni su quali tipi di simboli (n. :$set, n. :'this.that', ...) possono essere utilizzati con la sintassi in stile JavaScript. Il trunk attuale parse.y corrisponde a 1.9.3 per i valori letterali Hash.

Quindi la sintassi letterale Hash è cablata nel parser e si è bloccati con frecce grasse se si desidera supportare 1.8.

+0

risposta molto bella e completa, mu. Sembra che potrei dover riscrivere le istanze in cui utilizzo la sintassi in stile JS. Vorrei solo che ci fosse un modo per supportare versioni legacy senza scrivere codice legacy. Questa potrebbe essere la migliore scommessa però. – JackCA

1

Ruby 1.8.7 non supporta la nuova sintassi dell'hash.

Se hai un disperato bisogno di sintassi hash sulla non-YARV implementazione C a base di Ruby, c'è un ramo 1.8 di testa completamente supportato, in modo da can fai

rvm install ruby-head --branch ruby_1_8 ; rvm ruby-head 
ruby -v 
ruby 1.8.8dev (2011-05-25) [i386-darwin10.7.0] 

ma l'aggiornamento alla 1.9 è il modo di partire.

+0

Penso che l'intenzione di JackCA sia quella di fornire un gioiello a un Ruby 1.8 utenti possono usare, non che JackCA stia usando Ruby 1.8. Quindi non penso che questo aiuterà. – sawa