From: duerst@... Date: 2016-01-08T01:21:38+00:00 Subject: [ruby-core:72769] [Ruby trunk - Bug #11967] Mixing kwargs with optional parameters changes way method parameters are parsed Issue #11967 has been updated by Martin D��rst. Assignee set to Yukihiro Matsumoto This looks like a spec issue, so I have assigned it to Matz. I can see arguments for both ways, the current one and the one proposed by Markus. But we can't have it both ways :-(. ---------------------------------------- Bug #11967: Mixing kwargs with optional parameters changes way method parameters are parsed https://bugs.ruby-lang.org/issues/11967#change-56015 * Author: Markus Doits * Status: Open * Priority: Normal * Assignee: Yukihiro Matsumoto * ruby -v: ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin15] * Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN ---------------------------------------- I have the following method: def test(first_param = nil, keyword_arg: nil) puts "first_param: #{first_param}" puts "keyword_arg: #{keyword_arg}" end All the following calls do what I expect them to do: 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 But omitting the optional `keyword_arg` and passing a hash as first argument gives me an error: test(first_param: :is_a_hash) #=> test.rb:1:in `test': unknown keyword: first_param (ArgumentError) # from test.rb:12:in `
' I'd expect it to set `first_param` to `{ first_param: :is_hash }` and `keyword_arg` being `nil`. It seems it is interpreting every hash as keyword arg: test(keyword_arg: :should_be_first_param) #=> first_param: # keyword_arg: should_be_first_param This should have set `first_param` to `{ keyword_arg: :should_be_first_param }`, leaving `keyword_arg` `nil` in my opinion. Making the first parameter *mandatory* and everything works like I'd expect to: def test(first_param, keyword_arg: nil) puts "first_param: #{first_param}" puts "keyword_arg: #{keyword_arg}" end test(first_param: :is_a_hash) #=> first_param: {:first_param=>:is_a_hash} # keyword_arg: test(keyword_arg: :should_be_first_param) #=> first_param: {:keyword_arg=>:should_be_first_param} #=> keyword_arg: I'd expect making a parameter optional does not change the way parameters are parsed. Is this a parser oddity or expected behaviour? -- https://bugs.ruby-lang.org/ Unsubscribe: