2013-10-16 11 views
5

Voglio testare il valore di ritorno di un incarico in parallelo, e scrivo puts (x, y = 1, 2), ma non funziona, e stampare il messaggio di errore:Rubino assegnazione parallela

SyntaxError: (irb):74: syntax error, unexpected ',', expecting ')' 
puts (x,y =1,2) 
    ^
(irb):74: syntax error, unexpected ')', expecting end-of-input 

qualcosa che non va?

+0

provare senza lo spazio 'puts (x, y = 1,2)' – tihom

+2

puts ((a, b = 1, 2)) –

+2

Per favore, stand - e non mettere spazi prima delle parentesi argomento, per favore - matz. .. [ref] (http://www.justskins.com/forums/ruby-1-8-space-122361.html) – tihom

risposta

11

Hai due problemi.

  1. Lo spazio tra puts e ( impedisce la tupla venga interpretato come una lista di argomenti. Dopo aver inserito uno spazio dopo il nome di un metodo, qualsiasi elenco di argomenti deve essere al di fuori delle parentesi e qualsiasi parte tra parentesi deve essere un'espressione legale. In Ruby, (x,y,z) non è una singola espressione legale, quindi ottieni l'errore sopra riportato.

    Se si rimuove lo spazio, si ottiene questo:

    > puts(x, y = 1, 2)  
    NameError: undefined local variable or method `x' for main:Object 
    

    Questo è a causa del vostro secondo problema:

  2. La dichiarazione puts(x,y = 1,2) viene analizzato come puts(x, y=1, 2); cioè, Ruby lo interpreta come passare tre argomenti a puts: x è il primo, y=1 è il secondo e 2 è il terzo. Poiché lo x non si trova sul lato sinistro di un compito e non è ancora stato definito, si ottiene l'errore sopra riportato.

    Utilizzare un ulteriore set di parentesi per raggruppare l'intera assegnazione insieme come un solo argomento:

    > puts((x,y=1,2))  
    1  
    2  
    

Ma si noti che questo è il passaggio un unico elenco che contiene due elementi. Non fare la differenza con puts, ma sarà per i metodi che distinguono tra liste e singoli parametri:

> def foo(a,b) puts "a=#{a},b=#{b}" end 
> foo((x,y=1,2)) 
ArgumentError: wrong number of arguments (1 for 2) 

Quindi, in questo caso avete bisogno di un altro pezzo di punteggiatura - l'operatore splat:

> foo(*(x,y=1,2)) 
a=1, b=2 

Interessante, ma di scarsa rilevanza pratica, è il fatto che una volta che hai raddoppiato le parentesi, si può mettere lo spazio posteriore, se si desidera:

> puts ((x, y = 1, 2))  
1  
2  

Ma di nuovo, questo li trasforma da wrapper di argomenti in un semplice wrapper di espressioni; puoi mettere un numero qualsiasi di parentesi intorno a quello senza cambiare nulla.Ciò significa che nel caso foo, l'operatore splat deve andare al di fuori entrambi i gruppi di parentesi:

> foo (*(x,y=1,2)) 
SyntaxError: (irb):24: syntax error, unexpected tSTAR 
> foo *((x,y=1,2)) 
a=1, b=2 

E 'generalmente considerato cattivo stile in Ruby usare la forma parenthesisless quando il primo argomento in sé include parentesi, però. A seconda della versione di Ruby, è possibile che venga visualizzato un avviso su tali istruzioni, ma anche in caso contrario, è preferibile utilizzare la versione completamente con parentesi (senza spazio dopo il nome del metodo).

5

Questo dovrebbe funzionare

puts((x, y = 1, 2)) 
+1

Questo produrrà un avvertimento perché lo spazio tra 'puts' e' ('. – toro2k

2
puts((x, y = 1, 2)) 
# >> 1 
# >> 2 

Una serie di parentesi per il metodo di chiamata, un altro per la decorazione incarico come espressione esplicita.

1

mette è un metodo che accetta parametri e stampe. Nei metodi, è possibile impostare il valore del parametro su qualsiasi valore predefinito. Nel suo caso la sua assegnazione non parallela ma l'impostazione del valore predefinito. Se u fare

>puts(a, b = 1, 2) 
=> undefined local variable or method `a' for main:Object 
from (irb):1 

ma se u impostare il valore di 'a', diciamo 'a = 99' e fare

>puts(a, b = 1, 2) 
99 
1 
2 
=> nil 

In ruby, se u specificare la '()' in modo esplicito, cant u specificare uno spazio tra il nome del metodo e l'apertura (

def hi(x,y,z) 
    p x 
    p y 
    p z 
end 
=> nil 

2.0.0p247 :015 > hi(1,2,3) 
1 
2 
3 
=> 3 

2.0.0p247 :016 > hi (1,2,3) 
SyntaxError: (irb):16: syntax error, unexpected ',', expecting ')' 
hi (1,2,3) 
^
from /home/prasad/.rvm/gems/ruby-2.0.0-p247/gems/railties- 4.0.0/lib/rails/commands/console.rb:90:in `start' 
from /home/prasad/.rvm/gems/ruby-2.0.0-p247/gems/railties-4.0.0/lib/rails/commands/console.rb:9:in `start' 
from /home/prasad/.rvm/gems/ruby-2.0.0-p247/gems/railties-4.0.0/lib/rails/commands.rb:64:in `<top (required)>' 
from bin/rails:4:in `require' 
from bin/rails:4:in `<main>' 

2.0.0p247 :017 > hi 1, 2, 3 
1 
2 
3 
=> 3 
1

puts è un metodo, e si stanno cercando di superare il valore di ritorno di = (un incarico) ad esso. per fare ciò, bisogna avvolgerla in due coppie di parentesi:

puts((x, y = 1, 2)) 

Tuttavia, questo porta a codice confuso e dovrebbe essere evitato.

invece farlo in due fasi, è più facile e più pulito:

x, y = 1, 2 
puts x, y 

Inoltre, è possibile rimuovere la linea di puts senza rompere la funzionalità.