funciones - Llamar a una función de una cadena con el nombre de la función en Ruby
funciones de ruby (4)
Tres formas: send
/ call
/ eval
- y sus puntos de referencia
Invocación típica (para referencia):
s= "hi man"
s.length #=> 6
Usando send
s.send(:length) #=> 6
Usando call
method_object = s.method(:length)
p method_object.call #=> 6
Usando eval
eval "s.length" #=> 6
Puntos de referencia
require "benchmark"
test = "hi man"
m = test.method(:length)
n = 100000
Benchmark.bmbm {|x|
x.report("call") { n.times { m.call } }
x.report("send") { n.times { test.send(:length) } }
x.report("eval") { n.times { eval "test.length" } }
}
... como puede ver, la creación de instancias de un objeto de método es la forma dinámica más rápida para llamar a un método, también se observa qué lento es el uso de eval.
#######################################
##### The results
#######################################
#Rehearsal ----------------------------------------
#call 0.050000 0.020000 0.070000 ( 0.077915)
#send 0.080000 0.000000 0.080000 ( 0.086071)
#eval 0.360000 0.040000 0.400000 ( 0.405647)
#------------------------------- total: 0.550000sec
# user system total real
#call 0.050000 0.020000 0.070000 ( 0.072041)
#send 0.070000 0.000000 0.070000 ( 0.077674)
#eval 0.370000 0.020000 0.390000 ( 0.399442)
El crédito va a esta publicación de blog que elabora un poco más sobre los tres métodos y también muestra cómo verificar si los métodos existen.
¿Cómo puedo hacer lo que están hablando here , pero en Ruby?
¿Cómo harías la función en un objeto? y ¿cómo harías una función global (ver la answer de Jetxee en la publicación mencionada)?
EJEMPLO DE CÓDIGO:
event_name = "load"
def load()
puts "load() function was executed."
end
def row_changed()
puts "row_changed() function was executed."
end
#something here to see that event_name = "load" and run load()
ACTUALIZACIÓN: ¿Cómo se llega a los métodos globales? o mis funciones globales?
Intenté esta línea adicional
puts methods
y load y row_change donde no figuran.
Para llamar funciones directamente en un objeto
a = [2, 2, 3]
a.send("length")
que devuelve 3 como se esperaba
o para una función de módulo
FileUtils.send(''pwd'')
y un método definido localmente
def load()
puts "load() function was executed."
end
send(''load'')
Personalmente, configuraría un hash para utilizar referencias y luego usaría la cadena como un índice para el hash. A continuación, llama a la referencia de función con sus parámetros. Esto tiene la ventaja de no permitir que la cadena incorrecta llame a algo que no desea llamar. La otra forma es básicamente eval
la cadena. No hagas esto.
PD: no seas perezoso y realmente escribas tu pregunta completa, en lugar de vincularla a algo.
Utilizar esta:
> a = "my_string"
> meth = a.method("size")
> meth.call() # call the size method
=> 9
Simple, ¿verdad?
En cuanto a lo global , creo que el modo Ruby sería buscarlo usando el método de methods
.