From: ozydingo@... Date: 2016-01-07T02:34:11+00:00 Subject: [ruby-core:72743] [Ruby trunk - Bug #8316] Can't pass hash to first positional argument; hash interpreted as keyword arguments Issue #8316 has been updated by Andrew Schwartz. ruby -v changed from ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-linux] to ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin13] This is unfortunately still an issue with default values in positional arguments: 2.2.2 > def foo(hash={}, opt: true); p hash; p opt; end => :foo 2.2.2 > foo({a: 1}) ArgumentError: unknown keyword: a Expected behavior is that foo can be called with a hash argument in the first position without needing to specify the optional keyword args. Yusuke Endoh wrote: > This issue was solved with changeset r40992. > Pablo, thank you for reporting this issue. > Your contribution to Ruby is greatly appreciated. > May Ruby be with you. > > > ---------- > * vm_insnhelper.c (vm_callee_setup_keyword_arg, > vm_callee_setup_arg_complex): consider a hash argument for keyword > only when the number of arguments is more than the expected > mandatory parameters. [ruby-core:53199] [ruby-trunk - Bug #8040] > > * test/ruby/test_keyword.rb: update a test for above. ---------------------------------------- Bug #8316: Can't pass hash to first positional argument; hash interpreted as keyword arguments https://bugs.ruby-lang.org/issues/8316#change-55988 * Author: Tyler Rick * Status: Closed * Priority: Normal * Assignee: Yusuke Endoh * ruby -v: ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin13] * Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN ---------------------------------------- I'm able to pass any other type of object to my first argument: def foo(hash, opt: true) puts "hash: #{hash}, opt: #{opt.inspect}" end foo 'a' # => hash: a, opt: true foo [{a:1}] # => hash: [{:a=>1}], opt: true foo [{a:1}], opt: false # => hash: [{:a=>1}], opt: false But when I try to pass a hash, it raises an ArgumentError: foo({a:1}) # Raises ArgumentError: unknown keyword: a # Expected behavior: hash: {:a=>1}, opt: true I tried to work around the "unknown keyword" error by using ** but ended up getting a "wrong number of arguments (0 for 1)" error instead. def foo_with_extra(hash, **extra) puts "hash: #{hash}, extra: #{extra.inspect}" end foo_with_extra 'a' # hash: a, extra: {} foo_with_extra [{a:1}] # hash: [{:a=>1}], extra: {} foo_with_extra [{a:1}], opt: false # hash: [{:a=>1}], extra: {:opt=>false} foo_with_extra({a:1}) # Raises ArgumentError: wrong number of arguments (0 for 1) # Expected behavior: hash: {:a=>1}, extra: {} This behavior is surprising and I haven't seen it mentioned anywhere before. Is it really intentional? -- https://bugs.ruby-lang.org/ Unsubscribe: