2012-03-08 13 views
5

Me sorprende que Ruby 1.9 (JRuby 1.6.6 (RUBY_VERSION == "1.9.2") y Ruby 1.9.3-p125) den un error de sintaxis para puts(true and false).¿Por qué Ruby 1.9.2 da un error de sintaxis para: puts (true y false)?

No sé por qué, ¿cuál es el problema aquí? ¿Cómo escribiría esa pieza de código correctamente? puts(true && false) funciona, pero ¿hay alguna solución con and?

Ejemplo sesión de IRB:

1.9.3p125 :001 > puts(true and false) 
SyntaxError: (irb):1: syntax error, unexpected keyword_and, expecting ')' 
puts(true and false) 
      ^
    from /home/fr/.rvm/rubies/ruby-1.9.3-p125/bin/irb:16:in `<main>' 
1.9.3p125 :002 > puts(true && false) 
false 
=> nil 

Gracias a Mladen Jablanović para simplificar el ejemplo. El ejemplo anterior era f(true and f(false)).

+2

Tome un vistazo a http://stackoverflow.com/questions/1426826/difference-between-and-and-in-ruby – Thilo

+1

ejemplo simplificado sería 'puts (verdadero y falso)' –

+0

Gracias @Thilo y @Mladen. Conozco la precedencia del operador, pero para mí eso no explica el fenómeno. Gracias por el ejemplo 'puts', eso es mucho más simple. –

Respuesta

1

operator precedence en ruby ​​es && antes = antes and. Así que en su ejemplo usando and, sería tratar de hacer esta asignación (implícita):

puts(true 

y luego combinarlo con

false) 

través and, lo que provoca el error de sintaxis. Ver una gran explicación aquí: Difference between "and" and && in Ruby?

EDIT: No estoy seguro de si mi "asignación implícita" tiene sentido - pensar en esta declaración para que sea explícito:

foo = puts(true and false) 

EDIT 2: Recuerde que un método la llamada realmente se llama a un objeto. Por lo que las declaraciones equivalentes para los dos casos serían:

Object.send("puts", true && false) # this works 
Object.send("puts", true and false) # this is a syntax error 
Object.send("puts", (true and false)) # works again 

No estoy seguro si eso ayuda más - que tiene razón, que es un poco contra-intuitivo. Mi solución es que se mantenga alejado de and :)

+1

Eso es tan contra-intuitivo para mí. Esto implica que 'y' tiene una precedencia menor que el paréntesis de argumento de método. ¿Es esto solo un error en Ruby o hay un concepto detrás de esto que todavía no entiendo? –

3

Se trata de precedencias "y" y "& &" no tiene las mismas precedeces sobre operandos, trate de usar

f((true and f(false))) 

'y' se debe utilizar para algo como "haz las cosas A si esto funcionó bien, entonces haz cosas B" y no para una verificación booleana estricta.

check_db(param) and connect_db(param) 
+0

Buen punto sobre cuándo usar 'y', gracias. –

Cuestiones relacionadas