méthode d'envoi ruby ​​passant plusieurs paramètres

129

Essayer de créer des objets et d'appeler des méthodes dynamiquement en

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

qui fonctionne bien quand

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

mais lancer un nombre incorrect d'arguments 1 pour 2 pour

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

La classe aléatoire définie est

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

Quelqu'un peut-il m'aider sur la façon d'envoyer dynamiquement plusieurs paramètres à une méthode ruby

rails4sandeep
la source

Réponses:

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
la source
22
Il peut être intéressant de noter que *dans ce contexte, il s'agit de l'opérateur "splat".
Andrew Marshall
8

Vous pouvez alternativement appeler sendavec son synonyme __send__:

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

Au fait * vous pouvez passer des hachages en tant que paramètres séparés par des virgules comme ceci:

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

ou nouvelle syntaxe de hachage:

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

Selon Black, __send__est plus sûr pour l'espace de noms.

«L'envoi est un concept large: un e-mail est envoyé, les données sont envoyées aux sockets d'E / S, etc. Il n'est pas rare que les programmes définissent une méthode appelée send qui entre en conflit avec la méthode d'envoi intégrée de Ruby. Par conséquent, Ruby vous offre une autre façon d'appeler envoyer:__send__ . Par convention, personne n'écrit jamais une méthode avec ce nom, donc la version intégrée de Ruby est toujours disponible et n'entre jamais en conflit avec les méthodes nouvellement écrites. Cela semble étrange, mais c'est plus sûr que la version d'envoi simple du point de vue des conflits de nom de méthode "

Noir suggère également des appels d'emballage à __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

Réf: Black, David A. Le Rubyiste bien fondé. Manning, 2009. P.171.

* Je suis venu ici à la recherche d'une syntaxe de hachage pour __send__, donc cela peut être utile pour d'autres googleurs. ;)

Tony Cronin
la source