2015-09-25 3 views
0

у меня есть кусок тестового кода:Передача именованных аргументов и переменное число аргументов в вызове блока

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), не повезло.

ответ

2

Вы перепутали восклицательный знак и двойной восклицательный знак (примечание, что я изменил все *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 используется для неизвестного количества равнинных Params:

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

Double splat, введенный в Ruby2, используется для получения хеша (с указанием параметров):

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

Вы правы в ошибке ОП. Но, если быть точным, это не ** прямая ** причина синтаксической ошибки (это может вызвать ошибку аргумента). Причина синтаксической ошибки заключается в том, что именованный параметр ('state:: created') был помещен перед' * '. Однако вы указали на ** косвенную ** причину ошибки. – sawa

+0

Спасибо, это помогло! – Esa

Смежные вопросы