如何在ruby中混合使用必需参数和可选参数?

如何在ruby中混合使用必需参数和可选参数?,ruby,Ruby,我正在研究ruby,下面是我的代码片段。我尝试混合了必需参数和选项参数。但这给了我一个错误: def my_method(a, b, *p, d) puts a puts b puts "content of p is :" + p.to_s puts d end my_method(10, 20, 34, 45) 错误代码段: syntax error def my_method(a, b, *p, d)

我正在研究ruby,下面是我的代码片段。我尝试混合了必需参数和选项参数。但这给了我一个错误:

def my_method(a, b, *p, d)
    puts a
    puts b
    puts "content of p is :" + p.to_s
    puts d
end

my_method(10, 20, 34, 45)
错误代码段:

syntax error def my_method(a, b, *p, d)
                                     ^
这个错误的原因是什么

注意:我使用的是“ruby 1.8.5”ruby版本的数组splats(
*p
),它仅作为参数列表中的最后一个参数有效,因为它意味着“将传递给方法的所有剩余参数收集到数组
p

只需从方法签名中删除
d
,在您的方法中,只需设置
d=p.pop
,它就会工作。或者,将
d
移动到
*p

数组splats(the
*p
)之前,因为它意味着“将传递给方法的所有剩余参数收集到数组
p
”中,因此只有作为参数列表中的最后一个参数才有效


只需从方法签名中删除
d
,在您的方法中,只需设置
d=p.pop
,它就会工作。或者,将
d
移动到
*p
之前,您拥有的代码在任何最新版本的Ruby中都可以正常工作。但是,它在真正的Ruby旧版本中不起作用,因为splat参数之后需要的位置参数仅在Ruby 1.9.0中引入

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: #<Proc:0xdeadbeefc00l42@(irb):15> }
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)]]
结束
方法(:foo).arity
# => -5
方法(:foo).参数
#=>[: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:缺少关键字:mk1、mk2
foo(1,2,3,mk1:4,mk2:5)
#ArgumentError:参数数目错误(3代表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)完成15
#=>{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中都能正常工作。但是,它在真正的Ruby旧版本中不起作用,因为splat参数之后需要的位置参数仅在Ruby 1.9.0中引入

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: #<Proc:0xdeadbeefc00l42@(irb):15> }
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)]]
结束
方法(:foo).arity
# => -5
方法(:foo).参数
#=>[: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:缺少关键字:mk1、mk2
foo(1,2,3,mk1:4,mk2:5)
#ArgumentError:参数数目错误(3代表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,o