método de envio ruby ​​passando vários parâmetros

129

Tentando criar objetos e chamar métodos dinamicamente,

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

que está funcionando bem quando

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

mas jogando número errado de argumentos 1 para 2 para

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

A classe aleatória definida é

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

Alguém pode me ajudar sobre como enviar parâmetros múltiplos para um método ruby ​​dinamicamente

rails4sandeep
fonte

Respostas:

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

ou

send(:i_take_multiple_arguments, 25.0, 26.0)
Seanny123
fonte
22
Pode valer a pena notar que *, neste contexto, é o operador "splat".
Andrew Marshall
8

Você pode ligar alternadamente sendcom o sinônimo __send__:

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

By the way * você pode passar hashes como params vírgula separados da seguinte forma:

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

ou nova sintaxe de hash:

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

Segundo Black, __send__é mais seguro o espaço para nome.

“O envio é um conceito amplo: o email é enviado, os dados são enviados para os soquetes de E / S e assim por diante. Não é incomum que os programas definam um método chamado send que entra em conflito com o método de envio interno do Ruby. Portanto, Ruby lhe dá uma maneira alternativa para chamada de envio: __send__. Por convenção, ninguém nunca escreve um método com esse nome; portanto, a versão interna do Ruby está sempre disponível e nunca entra em conflito com os métodos recém-gravados. Parece estranho, mas é mais seguro do que a versão de envio simples do ponto de vista de conflitos de nome de método ”

Preto também sugere chamadas de embalar, __send__no 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. O Rubiista bem fundamentado. Manning, 2009. P.171.

* Eu vim aqui procurando por sintaxe de hash __send__, por isso pode ser útil para outros googlers. ;)

Tony Cronin
fonte