ruby syntax operators parameter-passing ruby-2.3

Que hace &.(ampersand dot) significa en Ruby?



syntax operators (4)

Me encontré con esta línea de código rubí. ¿Qué significa &. significa en esto?

@object&.method


¡Sé cauteloso! Aunque el operador de navegación segura es conveniente, también puede ser fácil engañarse para cambiar su lógica con él. Recomiendo evitar su uso en el control de flujo. Ejemplo:

str = nil puts "Hello" if str.nil? || str.empty? # The above line is different than the below line puts "Hello" if str&.empty?

En el primer ejemplo, str.nil? devuelve verdadero y str.empty? nunca se llama, lo que puts que se ejecute la instrucción put. En el segundo ejemplo, sin embargo, str&.empty? devuelve nil, que es falsey, y la instrucción put nunca se ejecuta.


Se llama el operador de navegación segura. Introducido en Ruby 2.3.0, le permite llamar a métodos en objetos sin preocuparse de que el objeto pueda ser nil (evitando un undefined method for nil:NilClass error undefined method for nil:NilClass ), similar al método try en Rails .

Entonces puedes escribir

@person&.spouse&.name

en vez de

@person.spouse.name if @person && @person.spouse

De los Docs :

my_object.my_method

Esto envía el mensaje my_method a my_object. Cualquier objeto puede ser un receptor pero, dependiendo de la visibilidad del método, enviar un mensaje puede generar un NoMethodError.

Puedes utilizar &. para designar un receptor, entonces my_method no se invoca y el resultado es nulo cuando el receptor es nulo. En ese caso, los argumentos de my_method no se evalúan.


se usaba para verificación nula, como en kotlin y swift Por ejemplo; con Objeto -> Swift y Kotlin

model = car?.model

este modelo puede ser nulo (Swift) o nulo (Kotlin) si no hemos definido el valor del modelo en la clase de automóvil. usamos ese signo en lugar de signo de interrogación en rubí

model = car&.model

si usa car.model sin ampersand y si el modelo es nulo, el sistema no puede continuar ejecutándose.


Nota: Aunque @Santosh dio una respuesta clara y completa, me gustaría agregar más antecedentes y una nota importante sobre su uso con variables que no son de instancia.

Se llama " Operador de navegación segura " ( también conocido como "Operador de encadenamiento opcional", "Operador condicional nulo", etc. ). Matz parece llamarlo "operador solitario". Fue introducido en Ruby 2.3 . Envía un método a un objeto solo si no es nil .

Ejemplo:

# Call method `.profile` on `user` only if `user` is not `nil` @user&.profile # Equivalent to unless @user.nil? @user.profile end

"Caso de borde" con variables locales:

Tenga en cuenta que el código anterior usa variables de instancia. Si desea utilizar un operador de navegación seguro con variables locales, primero deberá verificar que sus variables locales se definan.

# `user` local variable is not defined previous user&.profile # This code would throw the following error: NameError: undefined local variable or method `user'' for main:Object

Para solucionar este problema, verifique si su variable local se define primero o configúrela en nil:

# Option 1: Check the variable is defined if defined?(user) user&.profile end # Option 2: Define your local variable. Example, set it to nil user = nil user&.profile # Works and does not throw any errors

Fondo del método

Rails tiene un método de try que básicamente hace lo mismo. Utiliza el método de send internamente para llamar a un método. Matz sugirió que es lento y esto debería ser una función de lenguaje incorporada.

Muchos otros lenguajes de programación tienen características similares: Objetivo C, Swift, Python, Scala, CoffeeScript, etc. Sin embargo, una sintaxis común es ?. (punto de pregunta) Pero, esta sintaxis no pudo ser adoptada por Ruby. Porque ? fue permitido en nombres de métodos y por lo tanto ?. La secuencia de símbolos ya es un código Ruby válido. Por ejemplo:

2.even?.class # => TrueClass

Es por eso que la comunidad Ruby tuvo que proponer diferentes sintaxis. Fue una discusión activa y se consideraron diferentes opciones ( .? , ? , && , etc.). Aquí hay una lista de algunas consideraciones:

u.?profile.?thumbnails u/profile/thumbnails u!profile!thumbnails u ? .profile ? .thumbnails u && .profile && .thumbnails # And finally u&.profile&.thumbnails

Al elegir la sintaxis, los desarrolladores observaron diferentes casos límite y la discusión es bastante útil. Si desea ver todas las variantes y matices del operador, consulte esta discusión de introducción de características en el rastreador oficial de problemas de Ruby.