ruby中的函数无效

为什么这个function无效?

def request(method='get',resource, meta={}, strip=true) end 

未经预料的’)’期待keyword_end

谢谢!

在Ruby中,您不能使用可选参数包围所需参数。 运用

 def request(resource, method='get', strip=true, meta={}) end 

将解决问题。

作为思想实验,考虑原始function

 def request(method='get',resource, meta={}, strip=true) end 

如果我将该方法称为request(object) ,则所需的行为相当明显 – 使用object作为resource参数调用该方法。 但是,如果我将其称为request('post', object)呢? Ruby需要理解method的语义,以决定'post'method还是resource ,以及objectresource还是meta 。 这超出了Ruby的解析器的范围,因此它只会抛出无效的函数错误。

一些额外的提示:

我还会将meta参数放在最后,这允许您在没有花括号的情况下传递哈希选项,例如:

 request(object, 'get', true, foo: 'bar', bing: 'bang') 

正如Andy Hayden在评论中指出的那样,以下function有效:

 def f(aa, a='get', b, c); end 

将所有可选参数放在函数末尾通常是一种很好的做法,以避免按照这样的函数调用所需的心理体操。

参数列表中只能有一组可选参数。

Ruby中参数列表的伪正则表达式是这样的:

 mand* opt* splat? mand* (mand_kw | opt_kw)* kwsplat? block? 

这是一个例子:

 def foo(m1, m2, o1=:o1, o2=:o2, *splat, m3, m4, ok1: :ok1, mk1:, mk2:, ok2: :ok2, **ksplat, &blk) Hash[local_variables.map {|var| [var, eval(var.to_s)] }] end method(:foo).arity # => -5 method(:foo).parameters # => [[:req, :m1], [:req, :m2], [:opt, :o1], [:opt, :o2], [:rest, :splat], # [:req, :m3], [:req, :m4], [:keyreq, :mk1], [:keyreq, :mk2], # [:key, :ok1], [:key, :ok2], [:keyrest, :ksplat], [:block, :blk]] foo(1, 2, 3, 4) # ArgumentError: missing keywords: mk1, mk2 foo(1, 2, 3, mk1: 4, mk2: 5) # ArgumentError: wrong number of arguments (3 for 4+) foo(1, 2, 3, 4, mk1: 5, mk2: 6) # => { m1: 1, m2: 2, o1: :o1, o2: :o2, splat: [], m3: 3, m4: 4, # ok1: :ok1, mk1: 5, mk2: 6, ok2: :ok2, ksplat: {}, # blk: nil } foo(1, 2, 3, 4, 5, mk1: 6, mk2: 7) # => { m1: 1, m2: 2, o1: 3, o2: :o2, splat: [], m3: 4, m4: 5, # ok1: :ok1, mk1: 6, mk2: 7, ok2: :ok2, ksplat: {}, # blk: nil } foo(1, 2, 3, 4, 5, 6, mk1: 7, mk2: 8) # => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [], m3: 5, m4: 6, # ok1: :ok1, mk1: 7, mk2: 8, ok2: :ok2, ksplat: {}, # blk: nil } foo(1, 2, 3, 4, 5, 6, 7, mk1: 8, mk2: 9) # => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [5], m3: 6, m4: 7, # ok1: :ok1, mk1: 8, mk2: 9, ok2: :ok2, ksplat: {}, # blk: nil } foo(1, 2, 3, 4, 5, 6, 7, 8, mk1: 9, mk2: 10) # => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [5, 6], m3: 7, m4: 8, # ok1: :ok1, mk1: 9, mk2: 10, ok2: :ok2, ksplat: {}, # blk: nil } foo(1, 2, 3, 4, 5, 6, 7, 8, ok1: 9, mk1: 10, mk2: 11) # => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [5, 6], m3: 7, m4: 8, # ok1: 9, mk1: 10, mk2: 11, ok2: :ok2, ksplat: {}, # blk: nil } foo(1, 2, 3, 4, 5, 6, 7, 8, ok1: 9, mk1: 10, mk2: 11, ok2: 12) # => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [5, 6], m3: 7, m4: 8, # ok1: 9, mk1: 10, mk2: 11, ok2: 12, ksplat: {}, # blk: nil } foo(1, 2, 3, 4, 5, 6, 7, 8, ok1: 9, mk1: 10, mk2: 11, ok2: 12, k3: 13) # => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [5, 6], m3: 7, m4: 8, # ok1: 9, mk1: 10, mk2: 11, ok2: 12, ksplat: {k3: 13}, # blk: nil } foo(1, 2, 3, 4, 5, 6, 7, 8, ok1: 9, mk1: 10, mk2: 11, ok2: 12, k3: 13, k4: 14) # => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [5, 6], m3: 7, m4: 8, # ok1: 9, mk1: 10, mk2: 11, ok2: 12, ksplat: {k3: 13, k4: 14}, # blk: nil } foo(1, 2, 3, 4, 5, 6, 7, 8, ok1: 9, ok2: 10, mk1: 11, mk2: 12, k3: 13, k4: 14) do 15 end # => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [5, 6], m3: 7, m4: 8, # ok1: 9, mk1: 10, mk2: 11, ok2: 12, ksplat: {k3: 13, k4: 14}, # blk: # } 

[注意:必须在Ruby 2.1中引入强制关键字参数,所有其他参数已经有效。]

尝试重新排序您的参数:

 def Request(resource,strip=true,method='get',meta={}) end