: Double Pipe Es igual a
» Oye, ¿qué significa eso ||=
en tu código ruby?»
En mi primera entrada de blog como programador, pensé que sería apropiado explicar una de las preguntas que me hicieron durante mi primer día en la Escuela Flatiron. Esta es una pregunta que había surgido hace aproximadamente un mes y que me llevó a un agujero de conejo de foros de ruby y publicaciones de reddit (te ahorraré el problema y enlazaré algunas de las mejores fuentes al final de esta publicación).
La controversia detrás de «double-pipe equals» se centra en cómo se debe traducir el operador, pero me gustaría centrar este post en las aplicaciones que he encontrado para él. Entonces, ¿qué hace exactamente ||=
? Mi propia definición es que «double-pipe equals»es un operador que asigna un valor, al igual que =
o nuestro operador de asignación clásico, pero solo completará la asignación si el lado izquierdo de nuestra operación devuelve false
o nil
.
Déjame demostrártelo.
a = nil
b = 4
a = b #=> 4
a #=> 4
Con la etiqueta a
a nil
, es fácil ver que la fijación de un «igual» a b
clásico con el operador de asignación volvería a con el valor de 4
. Pero, ¿y si en su lugar usáramos «doble tubo igual»?
a = nil
b = 4
a ||= b #=> 4
a #=> 4
En este caso, obtenemos el mismo resultado. Cuando a
se establece en nil
(o cualquier cosa que evalúe a false
), el operador ||=
funciona igual que =
div > lo haría. Veamos un ejemplo en el que a
recibe un valor «verdadero».
a = 2
b = 4
a ||= b #=> 2
a #=> 2
En el ejemplo anterior, a conserva su valor original a pesar de que se ha operado a través de nuestro «doble tubo igual». Esto sucede porque ||
actúa como un «circuito» en este método. Como explica Peter Cooper,
Si el lado izquierdo de la comparación es verdadero, no es necesario verificar el lado derecho.
Cuando ruby vio que a
ya estaba asignado al valor de 2
, dejó de ejecutar nuestro código.
Donde he encontrado este tipo de asignación condicional más útil es en iteración. Vamos a recorrer una serie de frutas populares, utilizando nuestro método ||=
para asignar cada una de las cadenas a a
.
a = nil
array =
array.each do |fruit|
a ||= fruit
end #=> a #=> "apple"
podemos ver que, después de nuestra iteración, a
se asigna a la primera cadena en nuestra matriz, "apple”
. Después de que a
se convierta en "apple”
, nuestro «doble tubo igual» no permitirá que nada a su derecha reasigne nuestra variable.
Mientras que ruby tiene métodos que pueden devolver el primer elemento de una matriz sin iteración, a veces puede ser útil controlar si se ha asignado o no una variable con un valor «verdadero». A continuación se muestra un fragmento de código de uno de mis laboratorios recientes donde encontré ||=
particularmente útil.
class School attr_reader :roster def initialize(name)
@name = name
@roster = {}
end def add_student(name, grade)
@roster ||=
@roster << name
endend
Aquí, he definido una clase, School
, junto con un par de métodos. La clave a entender es que al llamar a roster
en una instancia de mi clase School
, estoy buscando devolver mi lista de estudiantes como un hash de calificaciones que apunta a una matriz de estudiantes asociados con cada calificación.
Permite crear una instancia de una escuela de ejemplo y rellenar algunos estudiantes.
metro = School.new("Metro High")
metro.add_student("Jared", 9)
metro.roster #=> {9=>}metro.add_student("Graham", 9)
metro.roster #=> {9=>}
Para agregar un estudiante a la etiqueta roster
mi School
instancia, tengo que pasar el add_student
método name
y un grade
. Sin embargo, podemos ver que cuando agregué "Graham”
y su grado correspondiente, 9
, su nombre se agregó al array existente que se creó cuando agregué "Jared”
. Esta es la magia de ||=
. En este caso, el operador «doble tubo igual» reconoció que ya se había agregado una clave de calificación y
Tenía mi add_student
método utilizado =
en lugar de ||=
, habría sobrescrito mi entrada de estudiante "Jared”
cuando agregué a otro estudiante en el grado 9
.