метод отправки ruby, передающий несколько параметров

129

Пытаться динамически создавать объекты и вызывать методы с помощью

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

который работает нормально, когда

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

но выбрасывает неправильное количество аргументов 1 для 2 для

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

Определенный случайный класс:

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

Может ли кто-нибудь помочь мне в том, как динамически отправлять несколько параметров методу ruby

rails4sandeep
источник

Ответы:

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

или

send(:i_take_multiple_arguments, 25.0, 26.0)
Seanny123
источник
22
Стоит отметить, что *в данном контексте оператор splat.
Эндрю Маршалл
8

Вы можете поочередно называть sendего синонимом __send__:

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

Кстати, * вы можете передавать хеши как параметры, разделенные запятыми:

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

или новый синтаксис хеша:

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

По словам Блэка, __send__безопаснее использовать пространство имен.

«Отправка - это широкое понятие: отправляется электронная почта, данные отправляются в сокеты ввода-вывода и так далее. Программы нередко определяют метод, называемый send, который конфликтует со встроенным в Ruby методом send. Следовательно, Ruby дает вам альтернативный способ вызова send : __send__. По соглашению, никто никогда не пишет метод с таким именем, поэтому встроенная версия Ruby всегда доступна и никогда не конфликтует с вновь написанными методами. Это выглядит странно, но с точки зрения конфликтов имен методов это безопаснее, чем обычная версия отправки »

Черные также предлагают заключить вызовы __send__в 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

Ссылка: Блэк, Дэвид А. Хорошо обоснованный рубист. Manning, 2009. P.171.

* Я пришел сюда в поисках синтаксиса хэша для __send__, поэтому может быть полезным для других гуглеров. ;)

Тони Кронин
источник