2009-08-26 12 views
11

Me encontré con un problema interesante al usar el método 'tap' en objetos del tipo 'String'.El método 'tap' en el objeto String no devuelve el resultado esperado

"abc".tap { |o| o = "xyz" } # this line returns "abc" instead of "xyz" 

El método 'tap' funciona en objetos de otros tipos.

[].tap { |o| o << "xyz" } # this line returns ["xyz"] as expected 

Estoy usando Rails 2.3.2 y Ruby 1.8.6 en Windows XP.

¿Qué me falta aquí?

Actualización 1: Resolví este problema. Fue un error de uso de mi parte. En el primer escenario, estaba reasignando el valor al parámetro de bloque en lugar de modificarlo. Pude reescribir el código y obtener el resultado esperado.

"abc".tap { |o| o.replace "xyz" } 

Actualización 2: El código utilizado aquí es solo para demostrar el problema. Mi código actual no se ve así.

+0

¿Podríamos tener un ejemplo real de lo que estás tratando de hacer? –

+1

Resolví este problema. Fue un error de uso de mi parte. En el primer escenario, estaba reasignando el valor al parámetro de bloque en lugar de modificarlo. Pude reescribir el código y obtener el resultado esperado. "abc" .tap {| o | o.replace "xyz"} –

Respuesta

8

Objeto # tap siempre devuelve el objeto original pasado después de ejecutar el bloque, incluso si el bloque devuelve algo diferente.

El beneficio aquí es que puede poner el grifo en el medio de una cadena y probar el valor de un objeto sin modificar el valor original.

Esto significa que si pasa "abc" al grifo, ejecutará el bloque y devolverá "abc". Su asignación a o no significa nada debido al alcance. Del mismo modo, si pasas una matriz vacía al tocar, devolvería una matriz vacía. Sin embargo, en su segundo ejemplo, modificó el valor original. Operaciones que modifican el original como < < o gsub! o también modificará el objeto antes de su devolución, por lo tanto, obtendrá un valor diferente.

Consulte http://moonbase.rydia.net/mental/blog/programming/eavesdropping-on-expressions para obtener algunos ejemplos más interesantes acerca de cómo usar el tap. No lo use para asignación o modificación, o obtendrá resultados retorcidos.

Actualización: Para su edición, ¿por qué eso resuelve su problema? No entiendo por qué llamarías a tocar para hacer un reemplazo cuando puedes simplemente reemplazar el objeto mismo. ¿Qué beneficio le está proporcionando el grifo?

+2

Sí, no tiene sentido utilizar 'tap' para hacer una simple sustitución. Mi código actual no se ve así. En lugar de publicar una gran parte del código, se me ocurrió este ejemplo para reproducir el problema. Tiendo a utilizar 'tap' para la depuración. Recientemente comencé a usar 'tap' en lugar de 'regresar'. Una vez que volví a leer el código fuente de Rails para el método de toque, mi error se hizo evidente. –

Cuestiones relacionadas