在Ruby中混合关键字和常规参数?
Ruby 2.0支持关键字参数。我想知道,将正则参数与关键字参数混合的“规则”是什么?像这样的事情是行不通的:在Ruby中混合关键字和常规参数?,ruby,Ruby,Ruby 2.0支持关键字参数。我想知道,将正则参数与关键字参数混合的“规则”是什么?像这样的事情是行不通的: def some_method(a: 'first', b: 'second', c) [a, b, c] end 但这将: def some_method(c, a: 'first', b: 'second') [a, b, c] end 那么,为什么将常规参数放在关键字参数之前(而不是之后)有效呢 网上有关于这个的参考资料吗(混合关键字和常规参数)?我好像找不到了。顺序
def some_method(a: 'first', b: 'second', c)
[a, b, c]
end
但这将:
def some_method(c, a: 'first', b: 'second')
[a, b, c]
end
那么,为什么将常规参数放在关键字参数之前(而不是之后)有效呢
网上有关于这个的参考资料吗(混合关键字和常规参数)?我好像找不到了。顺序如下:
- 必需参数
- 带有默认值的参数(
notation)arg=default\u值
- 可选参数(
符号,有时称为“splat参数”)*args
- 还是必需的参数
- 关键字参数
- 可选(
notation,从2.0.0开始)arg:默认值
- 与所需符号混合(
notation,从2.1.0开始)arg:
- 可选(
- 任意关键字参数(
表示法,从2.0.0开始)**args
- 块参数(
符号)&blk
def test(a, b=0, *c, d, e:1, f:, **g, &blk)
puts "a = #{a}"
puts "b = #{b}"
puts "c = #{c}"
puts "d = #{d}"
puts "e = #{e}"
puts "f = #{f}"
puts "g = #{g}"
puts "blk = #{blk}"
end
test(1, 2, 3, 4, 5, e:6, f:7, foo:'bar') { puts 'foo' }
# a = 1
# b = 2
# c = [3, 4]
# d = 5
# e = 6
# f = 7
# g = {:foo=>"bar"}
# blk = #<Proc:0x007fb818ba3808@(irb):24>
def测试(a、b=0、*c、d、e:1、f:、**g和blk)
将“a=#{a}”
放置“b=#{b}”
放置“c=#{c}”
放置“d=#{d}”
放置“e=#{e}”
放置“f=#{f}”
放置“g=#{g}”
放置“blk=#{blk}”
结束
测试(1,2,3,4,5,e:6,f:7,foo:'bar'){puts'foo'}
#a=1
#b=2
#c=[3,4]
#d=5
#e=6
#f=7
#g={:foo=>“bar”}
#blk=#
更详细的信息可从官方网站获得。Ruby中参数列表的伪正则表达式(同样适用于方法、块和lambda文本)如下所示:
mand* opt* splat? mand* (mand_kw | opt_kw)* ksplat? 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 2.1中将引入强制关键字参数,其他所有参数都已起作用。]
忘记了使用
**
符号的“任意关键字参数”,所以我也添加了这些参数。您也可以在splat之后使用强制参数。在Ruby 2.1中,还可以使用强制关键字参数,这些参数可以与可选关键字参数自由混合。见@JörgWMittag谢谢!我还注意到浏览文档的过程。将它添加到列表中。谢谢,这比接受的答案对我更有帮助。我知道这比公认的答案更能说明我的情况,但你看:)如果你是像我这样的新手,而这个答案毫无意义,请确保你向下滚动到@PatrickOscity的答案。