Ruby:使用可变参数发送(方法)吗?

时间:2018-11-01 14:16:58

标签: ruby api send

我正在开发一个小程序,以获取和发布API的多个资源。我程序的当前版本可以正常工作,但不是很清晰,所以现在我试图重构代码,以便更好地分离关注点(准备数据,发送数据,记录日志等)。但是现在我被卡住了。

我想出了一种方法,可以从另一个( send_data )方法(使用send)中发送方法( api_call ),该方法也可以发送到记录器中。这似乎是一个很好的关注点分离。但是,我不知道如何将必要的参数应用于我要发送的方法。

我尝试了其他一些与send和params有关的stackoverflow问题和教程,但是我似乎无法弄清楚如何正确地做到这一点。

如果我不包括参数,则显然会出现“ 0 for n”错误。如果尝试将它们包含在发送中,则会收到一条错误消息,告诉我它不需要参数。

  1. 从send_data内发送api_method的一种好方法是什么,同时允许我可变地设置参数?

  2. 也许应该在数组中设置参数,然后将该数组* splat作为参数?我不太确定该怎么做。

  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 :(得分:0)

最好只将条件用于此方法:

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 for n”错误。

尝试为当前方法指定所有args,好像错过了endpoint_URL

def api_call(endpoint_URL: _MISS_, resource: 'cases' , action: nil , method: 'get', uuid: nil)

答案 1 :(得分:0)

您问题中的方法api_call使用keyword arguments的现代语法。您可以使用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)