0

I'm working with Curb, a ruby wrapper around cURL.

I want to start by saying that I know methods such as method missing can accept arbitrary number args and a block if defined like so:

def method_missing(meth, *args, &block); ... end

*args is an array of parameters.

Now, I'm trying to refactor my calls to the HTTP GET, POST, etc methods, by doing the following with Curb:

req = Curl::Easy.send("http_#{method.to_s}", *args) do |curl| ... end

where args could be either 1 parameter or 2 parameters, which I'm trying to define as follows:

args = [url]
args << data if data

But I get an error when I invoke the Curl::Easy.send line.

both block arg and actual block given

here are some examples of the methods I'm trying to access from (https://github.com/taf2/curb/blob/master/lib/curl/easy.rb):

      def http_get(*args)
        c = Curl::Easy.new *args
        yield c if block_given?
        c.http_get
        c
      end 

      def http_put(url, data)
        c = Curl::Easy.new url
        yield c if block_given?
        c.http_put data
        c
      end

      def http_post(*args)
        url = args.shift
        c = Curl::Easy.new url
        yield c if block_given?
        c.http_post *args
        c
      end

      def http_delete(*args)
        c = Curl::Easy.new *args
        yield c if block_given?
        c.http_delete
        c
      end

all of them are set up to take arbitrary number of arguments, except put. But, really, for http_get I only need to pass a URL (with query params in the URL). so, I only want to pass one parametr for http_get, and 2 params for the others.

4

1 回答 1

0

如果我对您的理解正确,您希望根据方法的参数数量发送 x 个参数。以下将根据给定的数据工作。

method_name = "http_#{method.to_s}"
params = Curl::Easy.method(:"#{method_name}").parameters
req = Curl::Easy.send("http_#{method.to_s}", *(args[0..(params.size-1)])) do |curl| ... end```

但是,您出现的错误是当您将 Proc 作为参数发送并传递一个块时,它会按照您的要求执行,但是如果没有堆栈跟踪来缩小范围,我认为这不会解决您的错误。IE。

irb(main):001:0> def tst(&block)
irb(main):002:1> end
=> nil
irb(main):003:0> arg = Proc.new { }
=> #<Proc:0x00000002cd6930@(irb):3>
irb(main):004:0> tst(&arg) do
irb(main):005:1* end
SyntaxError: (irb):5: both block arg and actual block given

作为旁注,#parameters 返回类似的[[:rest][:args]]内容,并且 :rest 表示其余参数,因此您始终可以对参数进行更多检查以提供更细粒度的参数。

于 2014-08-28T19:29:29.490 回答