ruby precedence

Cuál es la precedencia de la llamada al método de Ruby



precedence (4)

http://phrogz.net/programmingruby/language.html#table_18.4 La tabla proporcionada por el enlace de arriba solo da la precedencia de los operadores de ruby. ¿Cuál es la precedencia de un método (o debería decir: un mensaje / función)?

Por ejemplo, cuando ingreso algo como a continuación en irb

Math.sqrt 2 + 2

Obtuve 2,0 como resultado. Sin las reglas definidas de la precedencia, simplemente no puedo decidir dónde usar los parens y dónde omitirlos. Entonces, alguien por favor ayúdame a deshacerme de esta incertidumbre. ¡Gracias por adelantado!


La invocación al método Ruby tiene una precedencia más baja que la de cualquiera de los operadores, pero esa no es la historia completa: hay algunos casos extremos que son obvios. Tu pregunta me hizo sentir curiosidad por uno de ellos, así que pregunté en la lista de correo de ruby ​​talk . Debería encontrar útil el hilo resultante.

Además, lea esta publicación de blog para un buen argumento de que debe usar generosamente paréntesis, especialmente mientras está aprendiendo ruby.


En Ruby, cualquier operador tiene prioridad sobre las llamadas a métodos, por ejemplo, los operadores se evalúan primero.

Sin embargo, el ejemplo Math.sqrt 2 + 2 es una buena ilustración de lo difícil de leer y poco intuitivo que puede ser dejar fuera paréntesis. Uno podría esperar que Math.sqrt(2) + 2 se evalúe aquí.

Cuando encuentres una línea como esta, podrías pensar: ¿Qué pretendía el codificador? ¿Es esto un error?

Siempre es una buena idea usar paréntesis siempre que sea posible, para dejar en claro lo que desea, especialmente cuando hay una llamada a un método o múltiples operadores; es solo un buen estilo y el enfoque de menor riesgo (por ejemplo, no hacer suposiciones, sino hazte claro usando paréntesis).

Nunca duele agregar paréntesis adicionales en las expresiones, pero dejarlos fuera puede doler un poco.

Aquí hay un buen ejemplo que encontré recientemente:

def foo(arg) raise "error" end x = foo 4 rescue 7 x => nil # oops! x = foo(4) rescue 7 x => 7

Espero que esto ilustra muy bien por qué es importante usar paréntesis

También:

Consulte aquí, en "Llamar a un método": http://ruby-doc.org/docs/ProgrammingRuby/html/tut_methods.html Cita:

[...] Si no hay ambigüedad, puede omitir los paréntesis alrededor de la lista de argumentos al llamar a un método. [...] Sin embargo, excepto en los casos más simples, no recomendamos esto --- hay algunos problemas sutiles eso puede hacerte tropezar. [En particular, debes usar paréntesis en una llamada a método que a su vez es un parámetro para otra llamada a método (a menos que sea el último parámetro).] Nuestra regla es simple: si hay alguna duda, usa paréntesis.

Ver también: http://phrogz.net/programmingruby/language.html


Cualquier operador tiene prioridad sobre la llamada al método. Se recomienda encarecidamente usar () para las llamadas a métodos para evitar situaciones como la que está preguntando.


Podemos utilizar su enlace Programming Ruby como punto de partida y descubrir por nosotros mismos dónde pertenecen las llamadas a métodos sin painterhesión en la tabla de precedencia. Solo mostraré las pruebas finales que señalan la ubicación.

Es más bajo que defined? :

defined? Math.sqrt 2 # => SyntaxError: unexpected tINTEGER, expecting end-of-input

Ajá, es más alto que not :

not Math.sqrt 2 => false

Ahora sabes exactamente cuándo deberías usar paréntesis.

Nota al margen

(gracias al enlace de Martin Demello con ruby-talk por recordarme)

Tenga en cuenta que los operadores de la tabla solo se aplican cuando no se utilizan en la sintaxis de llamada de método. Ejemplo: esto no obedece a las reglas para * y + porque no se utilizan como operadores, sino como métodos:

# This happens because unparenthesized method calls are right-associative. 2.* 5.+ 2 # => 14

Si eso parece confuso, lo mismo está sucediendo aquí:

# The `modulo` is evaluated first because it''s on the right Math.sqrt 9.modulo 5