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.