У меня есть следующий метод:
def test(first_param = nil, keyword_arg: nil)
puts "first_param: #{first_param}"
puts "keyword_arg: #{keyword_arg}"
end
Все следующие вызовы делают то, что я от них ожидаю:
test(:something)
#=> first_param: something
# keyword_arg:
test(nil, keyword_arg: :keyword_arg)
#=> first_param:
# keyword_arg: keyword_arg
test({ first_param: :is_a_hash }, keyword_arg: :is_still_working)
#=> first_param: {:first_param=>:is_a_hash}
# keyword_arg: is_still_working
Но опускание необязательного keyword_arg
и передача хэша в качестве первого аргумента дает мне ошибку:
test(first_param: :is_a_hash)
#=> test.rb:1:in `test': unknown keyword: first_param (ArgumentError)
# from test.rb:12:in `<main>'
Я ожидаю, что он установит first_param
на { first_param: :is_hash }
, а keyword_arg
на nil
.
Кажется, он интерпретирует каждый хэш как ключевое слово arg:
test(keyword_arg: :should_be_first_param)
#=> first_param:
# keyword_arg: should_be_first_param
Это должно было установить first_param
в { keyword_arg: :should_be_first_param }
, оставив, по моему мнению, keyword_arg
nil
.
Это ошибка парсера или ожидаемое поведение? Проверено на рубине 2.3.0 и 2.2.4.
Изменить: сделать первый параметр обязательным, и все работает так, как я ожидал:
def test_mandatory(first_param, keyword_arg: nil)
puts "first_param: #{first_param}"
puts "keyword_arg: #{keyword_arg}"
end
test_mandatory(first_param: :is_a_hash)
#=> first_param: {:first_param=>:is_a_hash}
# keyword_arg:
test_mandatory(keyword_arg: :should_be_first_param)
#=> first_param: {:keyword_arg=>:should_be_first_param}
# keyword_arg:
Я ожидаю, что необязательный параметр не изменит способ анализа параметров.
Я открыл проблему на bugs.ruby-lang.org, чтобы разработчики могли разобраться независимо от того, предназначено ли это для этого или является побочным эффектом kword args.
first_param
на{ keyword_arg: :should_be_first_param }
, оставив, по моему мнению,keyword_arg
nil
. -- Почему? Разве вы не ожидали, что это будет двусмысленно? - person sawa   schedule 07.01.2016first_param
(test(:something)
). Но если параметр является хэшем, он не устанавливаетfirst_param
, а интерпретирует хэш как аргументы ключевого слова. Почему поведение зависит от типа параметра? Это не логично (по крайней мере для меня). - person Markus   schedule 07.01.2016