rails ruby

rails - Método Ruby ''tap''-dentro de la asignación



rails tap (2)

En el primer caso, la array y el punto apuntan al mismo objeto. Luego, muta ese objeto usando el método << . El objeto al que se array tanto la array como el punto de ary ahora se cambia.

En el segundo caso, array y ary nuevamente apuntan a la misma matriz. Ahora reasigna la variable ary , de modo que ary ahora apunta a una nueva matriz. Sin embargo, la reasignación de ary no tiene ningún efecto en la array . En ruby, la reasignación de una variable nunca afecta a otras variables, incluso si apuntaban al mismo objeto antes de la reasignación.

En otras palabras, la array aún está vacía por la misma razón que x no será 42 en el siguiente ejemplo:

x = 23 y = x y = 42 # Changes y, but not x

Editar: para agregar una matriz a otra en el lugar, puede usar el método concat , que también debería ser más rápido que usar += .

Recientemente descubrí que el tap se puede usar para "secamente" asignar valores a nuevas variables; por ejemplo, para crear y rellenar una matriz, como esto:

array = [].tap { |ary| ary << 5 if something }

Este código empujará 5 en la array si something es verdadero; de lo contrario, la array permanecerá vacía.

Pero no entiendo por qué después de ejecutar este código:

array = [].tap { |ary| ary += [5] if something }

array permanece vacía. ¿Alguien puede ayudarme?


Quiero ampliar esto un poco:

array = [].tap { |ary| ary << 5 if something }

Lo que esto hace (asumiendo que something es verdadero):

  1. asigna una array a [] , una matriz vacía.

    array.object_id = 2152428060

  2. Pasa [] al bloque como ary . ary y array están apuntando al mismo objeto de array.

    array.object_id = 2152428060 ary.object_id = 2152428060

  3. ary << 5 << es un método mutativo, lo que significa que modificará el objeto receptor. ¡Es similar al lenguaje de anexar ! a una llamada de método, que significa "¡modifique esto en su lugar!", como en .map vs .map! (aunque el bang no tiene ningún significado intrínseco en un nombre de método). ary tiene 5 insertados, entonces ary = array = [5]

    array.object_id = 2152428060 ary.object_id = 2152428060

Terminamos con la array siendo igual a [5]

En el segundo ejemplo:

array = [].tap{ |ary| ary += [5] if something }

  1. mismo
  2. mismo
  3. ary += 5 += es la abreviatura de ary = ary + 5 , por lo que es la primera modificación ( + ) y luego la asignación ( = ), en ese orden. Da la apariencia de modificar un objeto en su lugar, pero en realidad no lo hace. Crea un objeto completamente nuevo.

    array.object_id = 2152428060 ary.object_id = 2152322420

Así que terminamos con la array como el objeto original, una matriz vacía con object_id=2152428060 , y ary , una matriz con un elemento que contiene 5 con object_id = 2152322420 . Nada le sucede a ary después de esto. No está involucrado con la asignación original de la array , que ya ha sucedido. Tap ejecuta el bloque después de que se haya asignado la array .