aliasing un método resulta en diferentes objetos?
-
05-07-2019 - |
Pregunta
def foo
"foo"
end
alias foo2 foo
puts "foo2: " + foo2.object_id.to_s
puts "foo: " + foo.object_id.to_s
En el ejemplo anterior, esperaba ver la misma salida de object_id para cada llamada al método ya que hacen referencia al mismo método. ¿Por qué veo diferentes object_id's? Cuando alias un método en Ruby, ¿el alias no se refiere al objeto original, no a una copia?
Solución
Comenzando de nuevo con una nueva respuesta en respuesta a sus diversos comentarios.
En el código de ejemplo, está llamando al método, no haciendo referencia a él. Quieres usar
method(:foo)
para obtener el método en sí y no el resultado de llamarlo.
Además, object_id
no es la forma correcta de probar si dos métodos son iguales, porque method (: foo)
devuelve un nuevo objeto Method cada vez. Para una analogía que podría aclarar esto, si abrieras el mismo archivo dos veces, tendrías dos identificadores de archivo distintos aunque el archivo subyacente fuera el mismo. En cambio, creo que quieres:
method(:foo) == method(:foo2)
que, como verá si lo prueba, devuelve true
.
Otros consejos
Estás llamando a object_id
en el objeto devuelto por foo
, que es una cadena creada en el método y, por lo tanto, será diferente cada vez. Vería los mismos resultados si acaba de llamar foo
dos veces. Devuelve una nueva cadena cada vez. Si desea una cadena constante, devuelva el símbolo : foo
en su lugar.
Más allá de eso, aunque compartan la misma implementación en este momento, son métodos diferentes. Si reemplaza foo
para devolver la cadena " barra " ;, foo2
seguirá retornando " foo " ;.
Prueba:
FOO = "foo"
def foo
FOO
end
alias foo2 foo
puts "foo2: " + foo2.object_id.to_s
puts "foo: " + foo.object_id.to_s
Para obtener el efecto que deseas. " foo " es una expresión y se evalúa cada vez que se llama a la función. Para ver por qué esto es así, considera que podrías haber escrito:
def foo
"It is now #{Time.now}"
end
alias foo2 foo
puts "foo2: " + foo2.object_id.to_s
puts "foo: " + foo.object_id.to_s