[英]Mixing keyword with regular arguments in Ruby?
Ruby 2.0 supports keyword arguments. Ruby 2.0支持关键字参数。 I was wondering, what are the 'rules' for mixing regular with keyword arguments? 我想知道,将常规与关键字参数混合的“规则”是什么? Something like this would not work: 这样的事情是行不通的:
def some_method(a: 'first', b: 'second', c)
[a, b, c]
end
but this will: 但这将:
def some_method(c, a: 'first', b: 'second')
[a, b, c]
end
So why does putting a regular argument before the keyword arguments (and not after) works? 那么,为什么在关键字参数之前(而不是之后)放置常规参数呢?
Is there some reference on the web on this (mixing keyword and regular arguments)? 网络上是否有一些参考(混合关键字和常规参数)? I can't seem to find any. 我似乎找不到任何东西。
The order is as follows: 顺序如下:
arg=default_value
notation) 具有默认值的参数( arg=default_value
表示法) *args
notation, sometimes called "splat parameter") 可选参数( *args
表示法,有时称为“ splat参数”) arg:default_value
notation, since 2.0.0) 可选( arg:default_value
表示法,从2.0.0开始) arg:
notation, since 2.1.0) 与required混合( arg:
表示法,自2.1.0起) **args
notation, since 2.0.0) 任意关键字参数( **args
表示法,自2.0.0开始) &blk
notation) 块参数( &blk
表示法) For example: 例如:
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>
More detailed information is available from the official Ruby Syntax Documentation . 可以从官方的Ruby语法文档中获得更多详细信息。
A pseudo-regex for parameter lists in Ruby (this applies equally to methods, blocks and lambda literals) is something like this: Ruby中参数列表的伪正则表达式(这同样适用于方法,块和lambda文字)如下所示:
mand* opt* splat? mand* (mand_kw | opt_kw)* ksplat? block?
Here's an example: 这是一个例子:
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> }
[Note: mandatory keyword arguments will be introduced in Ruby 2.1, all the rest already works.] [注意:必填关键字参数将在Ruby 2.1中引入,其余所有参数都已经可用。]
Double splat argument must appear last but before block argument. 双splat参数必须出现在最后但在块参数之前。
def foo(a, b=1, c=2, *d, e, f: 1, g: 2, **kwargs, &block) def foo(a,b = 1,c = 2,* d,e,f:1,g:2,** kwargs,&block)
Keyword arguments is just an optional hash argument, as I know. 据我所知,关键字参数只是一个可选的哈希参数。
def some_method(c, a: 'first', b: 'second')
is same as 与...相同
def some_method(c, { a: 'first', b: 'second' }) // will not compile actually
Ruby just interprets last arguments with hash syntax as hash. Ruby只是将使用哈希语法的最后一个参数解释为哈希。 So the first example doesn't work because ruby can't understand such syntax (has syntax at first place). 因此第一个示例不起作用,因为ruby无法理解这样的语法(首先是语法)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.