Ruby public_send метод с хэш-параметрами, где это применимо - PullRequest
0 голосов
/ 05 июня 2018

Tldr: я пытаюсь использовать public_send для вызова методов, но некоторые из этих методов также требуют аргументов.Как проверить, какие аргументы требуются, добавить их в качестве аргументов и включить их в вызов

У меня есть массив методов в таком классе, как этот
class_methods = [:first, :second, :third, :fourth] ...

Iопределил метод can_execute, чтобы проверить, есть ли у класса метод, если он так будет выполняться.

def can_execute (class, method_name)
  if class.respond_to?(method_name.to_sym) && class.class_methods.include?(method_name.to_sym)
    class.public_send(method_name)
  end
end

Когда пользователь предоставляет какой-либо из этих class_method в качестве аргумента, я могу вызвать их следующим образом
can_execute(class, method_name)

Проблема в том, что некоторые из этих методов принимают хэш в качестве аргументов, например
class.first(Value: true) или
class.second(Id: 0, Value: "string")

Но некоторые не
class.third

Я не уверен, как включить хэш params для некоторых из этих class_methods require?

У меня есть возможность проверить, какие аргументы нужны этим методам, вызвав method_args onих, как

class.method_args(:first)
-> [:Value]

class.method_args(:second)
=> [:Id, :Value]

class.method_args(:third)
=> []

1 Ответ

0 голосов
/ 05 июня 2018

Вам нужно будет передать аргументы can_execute, чтобы он мог передать их public_send.Оператор сплат здесь ваш друг.При использовании в качестве параметра он будет заключать любое количество аргументов в массив со своим именем.При использовании в массиве он разбивает массив на аргументы для передачи методу.

В дополнение к этому, class является ключевым словом.Соглашение состоит в том, чтобы называть его klass, но это может быть как угодно (кроме класса)

С учетом этого наш новый метод выглядит следующим образом:

def can_execute (klass, method_name, *args)
  if klass.respond_to?(method_name.to_sym) && klass.class_methods.include?(method_name.to_sym)
    klass.public_send(method_name, *args)
  end
end

Тогдапозвонить, может иметь параметры или нет.Не нужно сначала проверять:

can_execute('teststring', :slice, 1, 5) # => "ests"
can_execute('teststring', :upcase) # => "TESTSTRING"

Если у вас есть еще одна причина для проверки параметров, вы можете использовать Method#arity или Method#parameters.Примерно так с результатами для #slice

klass.method(method_name.to_sym).arity # => -1
klass.method(method_name.to_sym).parameters # => [[:rest]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...