Ruby: отправить (метод) с переменными параметрами? - PullRequest
0 голосов
/ 01 ноября 2018

Я работаю над небольшой программой, чтобы получить доступ к нескольким ресурсам API и опубликовать их. Текущая версия моей программы работает нормально, но не очень разборчиво, поэтому сейчас я пытаюсь реорганизовать свой код для лучшего разделения проблем (подготовка данных, отправка данных, ведение журнала и т. Д.). Но теперь я застрял.

Я нашел способ отправки метода ( api_call ) из другого ( send_data ) метода (с использованием send), который также подается в регистратор. Это похоже на хорошее разделение проблем. Однако я не могу понять, как применить необходимые параметры к методу, для которого я отправляю.

Я пытался следовать нескольким другим вопросам и учебникам по стековому потоку, связанным с send и params, но я не могу понять, как это сделать правильно.

Если я не включаю параметры, я, очевидно, получаю ошибку «0 для n». Если я пытаюсь включить их в отправку, я получаю сообщение об ошибке, в котором говорится, что параметры не ожидаются.

  1. Что было бы хорошим способом отправить для api_method из send_data, позволяя мне по-разному устанавливать параметры?

  2. Должен ли я установить параметры в массиве и * выделить этот массив как параметры? Я не совсем уверен, как бы я это сделал.

  3. Это даже умный способ приблизиться к этому? Я думаю, что я мог бы просто создать еще несколько методов для различных ресурсов, которые наследуются от "api_call", чтобы я мог избавиться от большинства параметров? Но это не кажется очень сухим?

Вот упрощенный пример моего кода:

class ApiConnector

  def send_data(method_name)
    begin
      @attempts += 1
      puts "#{@attempts}th attempt"
      send(method_name)     # (how) do I set params here?
    rescue Errno::ETIMEDOUT => e
      retry if @attempts < 3
    end
  end

  def api_call(endpoint_URL: , resource: 'cases' , action: nil , method: 'get', uuid: nil)
    request = Typhoeus::Request.new(
      "#{endpoint_URL}/api/v1/#{resource}/#{uuid}/#{action}",
      verbose: true,
      method: :post,
      headers: { 'Content-Type' => "multipart/form-data", "API-key" => "123", "API-Interface-ID" => "123", "User-Agent" => "AGENT" }
    )

    request.run 
  end

end

Любые ссылки на соответствующую документацию также приветствуются. Очень благодарен.

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

В методе api_call из вашего вопроса используется современный синтаксис аргументов ключевых слов . Вы можете вызвать этот метод, используя send с аргументами, переданными в виде хэша:

params = {
  endpoint_URL: 'https://www.google.com',
  # other params
}
send(:api_call, params)

(Так как аргумент endpoint_URL не имеет значения по умолчанию, вы должны передать его, чтобы избежать ошибки ArgumentError)


Если метод был написан с использованием общих позиционных аргументов:

def api_call(endpoint_URL, resource = 'cases' , action = nil , method = 'get', uuid = nil)
  # ...
end

вы также можете вызвать его с send, но массив аргументов должен быть * splat:

params = [
  'https://www.google.com',
  # other params
]
send(:api_call, *params)
0 голосов
/ 01 ноября 2018

возможно, лучше использовать условие исключительно для этого метода:

if method == :api_call
  send method_name, endpoint_URL: __TEST_URL__, resource: 'cases' , action: nil , method: 'get', uuid: nil
else
  send method_name
end

Если я не включаю параметры, я, очевидно, получаю ошибку «0 для n».

попытаться указать все аргументы для текущего метода, похоже, пропущено endpoint_URL:

def api_call(endpoint_URL: _MISS_, resource: 'cases' , action: nil , method: 'get', uuid: nil)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...