在块调用中传递命名参数和可变数量的参数

时间:2015-09-25 07:09:45

标签: ruby syntax yield

我有一段测试代码:

def asdf(id: nil, field: nil, state: nil)
  puts "id: #{id}, field: #{field}"
end

def test(a, b, *args)
  # a, b are needed only inside #test
  yield(state: :created, *args)
end

test('a', 'b', id: 'xyz', field: :asd) { |*args| asdf(*args) }

它会生成语法错误:

syntax error, unexpected *
yield(state: :created, *args)

使用命名参数和参数列表调用块的正确方法是什么?这样做的惯用方法是什么?

我还尝试将&block传递给test,并在没有运气的情况下执行block.call(state: :created, *args)

1 个答案:

答案 0 :(得分:2)

你混合了splat和double splat(注意,我将所有*args更改为**args):

def asdf(id: nil, field: nil, state: nil)
  puts "id: #{id}, field: #{field}"
end

def test(a, b, **args)
  # a, b are needed only inside #test
  yield(state: :created, **args)
end

test('a', 'b', id: 'xyz', field: :asd) { |**args| asdf(**args) }
#⇒ id: xyz, field: asd

Splat用于未知数量的普通参数:

def test a, b, *args
  puts args.inspect
end
test 42, true, 'additional'
#⇒ ["additional"]

Ruby2中引入的双splat用于接收哈希(命名为params):

def test a, b, **args
  puts args.inspect
end
test 42, true, hello: 'world'
#⇒ {:hello=>"world"}