método de envío ruby ​​que pasa múltiples parámetros

129

Intentando crear objetos y métodos de llamada dinámicamente por

Object.const_get(class_name).new.send(method_name,parameters_array)

que funciona bien cuando

Object.const_get(RandomClass).new.send(i_take_arguments,[10.0])

pero arrojando un número incorrecto de argumentos 1 por 2 para

Object.const_get(RandomClass).new.send(i_take_multiple_arguments,[25.0,26.0])

La clase aleatoria definida es

class RandomClass
def i_am_method_one
    puts "I am method 1"
end
def i_take_arguments(a)
    puts "the argument passed is #{a}"
end
def i_take_multiple_arguments(b,c)
    puts "the arguments passed are #{b} and #{c}"
end
    end

¿Alguien puede ayudarme a enviar dinámicamente múltiples parámetros a un método ruby?

rails4sandeep
fuente

Respuestas:

232
send("i_take_multiple_arguments", *[25.0,26.0]) #Where star is the "splat" operator

o

send(:i_take_multiple_arguments, 25.0, 26.0)
Seanny123
fuente
22
Vale la pena señalar que el * en este contexto es el operador "splat".
Andrew Marshall
8

Alternativamente puede llamar sendcon su sinónimo __send__:

r = RandomClass.new
r.__send__(:i_take_multiple_arguments, 'a_param', 'b_param')

Por cierto * puede pasar hashes como parámetros separados por comas de la siguiente manera:

imaginary_object.__send__(:find, :city => "city100")

o nueva sintaxis hash:

imaginary_object.__send__(:find, city: "city100", loc: [-76, 39])

Según Black, __send__es más seguro para el espacio de nombres.

“El envío es un concepto amplio: se envía un correo electrónico, se envían datos a los zócalos de E / S, y así sucesivamente. No es raro que los programas definan un método llamado envío que entre en conflicto con el método de envío incorporado de Ruby. Por lo tanto, Ruby le da una forma alternativa de enviar la llamada: __send__. Por convención, nadie escribe un método con ese nombre, por lo que la versión incorporada de Ruby siempre está disponible y nunca entra en conflicto con los métodos recién escritos. Parece extraño, pero es más seguro que la versión de envío simple desde el punto de vista de los conflictos de nombre de método "

Negro también sugiere llamadas a envolver __send__en if respond_to?(method_name).

if r.respond_to?(method_name)
    puts r.__send__(method_name)
else
    puts "#{r.to_s} doesn't respond to #{method_name}"
end

Ref: Black, David A. El bien fundamentado Rubyist. Manning, 2009. P.171.

* Vine aquí buscando sintaxis hash __send__, por lo que puede ser útil para otros googlers. ;)

Tony Cronin
fuente