2013-02-19 10 views
6

Per farla breve, stavo scrivendo un metodo che includeva un argomento di opzioni, che farà certe cose se il valore per la chiave: if, valutato su true. Quando ho provato la hash nella IRB utilizzando la nuova sintassi ho ottenuto un errore di sintassi nella IRB, i soggiorni Aprire il prompt:IRB - Sintassi hash di Ruby 1.9.x: {if: true} non è uguale a {: if => true}

1.9.3p374 :010 > {if: true} 
1.9.3p374 :011?> 

Utilizzando la vecchia sintassi, funziona bene:

1.9.3p374 :011 > {:if => true} 
=> {:if=>true} 

Tutte le parole chiave che iniziare una dichiarazione, esibire lo stesso comportamento. Per esempio. def, do, module, case

Altre parole riservate che si verificano nel mezzo e class funzionano bene: else, end

La mia domanda è: È questo il comportamento previsto, un bug o una limitazione?

+2

'irb' è un po 'fragile e ha una discreta quantità di danni al cervello, probabilmente stai vedendo un po' di quello. –

+0

@muistooshort che sembra piuttosto infondato. 'echo 'mette {if: true} .inspect'> test.rb; ruby test.rb' restituisce: 'test.rb: 1: errore di sintassi, imprevisto ':'' In che modo è 'irb' fragile? – nzifnab

+2

@nzifnab Irb deve tenere a bada l'esecuzione dell'istruzione fino alla fine, e se interpreta erroneamente un operatore di controllo (come fa qui) ci sono altri problemi esclusivi. – coreyward

risposta

6

È difficile analizzare in modo affidabile e inequivocabile le cose in qualsiasi lingua. Questo è particolarmente vero quando inizi a usare parole riservate. E irb deve andare oltre e fornire un modello interattivo in cima al parser, che è ancora più difficile. Personalmente non penso che ci sia troppa importanza nel preoccuparsi di casi come questo, sia come utente della lingua che come manutentore. Nella mia mente, è meglio capire semplicemente cosa funziona ed evitare di entrare in queste situazioni, se possibile.

È possibile visualizzare alcuni comportamenti simili in Ruby chiaro, al di fuori dello irb. Per esempio:

puts({if: true}) # no problem, behaves as expected in Ruby 1.9.3. 
puts {if: true} # raises a syntax error in Ruby 1.9.3 

Per rispondere alla tua domanda, è "un comportamento previsto, un bug o una limitazione", direi che si dovrebbe ignorare irb e confrontarlo pianura Ruby, e se lo fai questo, funziona bene. Ciò significa che deve essere un bug irb.

Ma è possibile o utile da risolvere? @coreyward fa un buon punto nel suo commento che irb deve ritardare l'esecuzione nella maggior parte dei casi quando incontra uno if. Dovresti cercare ancora di più per essere sicuro, ma potresti non essere in grado di interpretare senza ambiguità tutti i casi come questo.

Il mio consiglio: evita del tutto questo costrutto se puoi, e non usare parole riservate per le etichette se puoi evitarlo!

Ecco un file che è possibile eseguire con semplice Ruby (ad esempio, la risonanza magnetica). Dovresti vedere {:if=>true} nell'output per confermare che funzioni.

{if: true} 
foo = {if: true} 
# if MRI is working, should be able to execute this file without trouble. 
p foo 
+1

Vale anche la pena notare che se si introduce il compito tutto funziona come previsto. Per esempio.'foo = {if: true}' valuta la multa in MRI (sebbene IRB salga ancora su). – coreyward

+0

@coreyward: davvero. Ho provato questo. Aggiungerò un blocco di codice alla mia risposta per chiarire. Grazie! – Peter

+1

Tutto molto interessante. L'esempio dell'OP fallisce se in uno script ruby ​​o in IRB, ma quando si lancia una parentesi intorno alle puts funziona. Come confuso! Vorrei quasi che si attaccassero esclusivamente con il razzo hash. Molto più facile da capire e molti meno trucchi (e poi tutti gli hash sono gli stessi invece degli "hash con i tasti delle corde usano i razzi! Gli hash con le etichette riservate usano i razzi! A volte i simboli dovrebbero usare la sintassi dell'etichetta!) Ugh. – nzifnab