Ruby send metoda przekazująca wiele parametrów

131

Próba dynamicznego tworzenia obiektów i wywoływania metod przez

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

który działa dobrze, kiedy

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

ale rzuca złą liczbę argumentów 1 za 2 dla

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

Zdefiniowana klasa losowa to

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

Czy ktoś może mi pomóc w dynamicznym wysyłaniu wielu parametrów do metody ruby

rails4sandeep
źródło

Odpowiedzi:

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

lub

send(:i_take_multiple_arguments, 25.0, 26.0)
Seanny123
źródło
22
Warto zauważyć, że *w tym kontekście jest to operator „splat”.
Andrew Marshall
8

Możesz na przemian zadzwonić sendpodając jego synonim __send__:

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

Przy okazji * możesz przekazywać skróty jako parametry oddzielone przecinkami w następujący sposób:

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

lub nowa składnia skrótu:

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

Według Blacka __send__jest bezpieczniejsza dla przestrzeni nazw.

„Wysyłanie to szerokie pojęcie: e-mail jest wysyłany, dane są wysyłane do gniazd I / O i tak dalej. Nierzadko programy definiują metodę o nazwie send, która koliduje z wbudowaną metodą wysyłania Rubiego. Dlatego Ruby daje alternatywny sposób wywoływania Wyślij: __send__. Zgodnie z konwencją, nikt nigdy nie pisze metody o tej nazwie, więc wbudowana wersja Ruby jest zawsze dostępna i nigdy nie wchodzi w konflikt z nowo napisanymi metodami. Wygląda dziwnie, ale jest bezpieczniejsze niż wersja zwykłego wysyłania z punktu widzenia kolizji nazwy metody ”

Czarny sugeruje również połączenia do zawijania __send__w 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. Dobrze ugruntowany rubinista. Manning, 2009. str.171.

* Przyszedłem tutaj, szukając składni hash dla __send__, więc może być przydatna dla innych pracowników Google. ;)

Tony Cronin
źródło