From: merch-redmine@... Date: 2019-08-30T21:46:26+00:00 Subject: [ruby-core:94693] [Ruby master Bug#12717] Optional argument treated as kwarg Issue #12717 has been updated by jeremyevans0 (Jeremy Evans). Status changed from Open to Closed With the changes in #14183: ```ruby Foo.options({}) # (irb):21: warning: The last argument for `options' (defined at (irb):6) is used as the keyword parameter # nil # {} Foo.kwarg({}) # (irb):22: warning: The last argument for `kwarg' (defined at (irb):11) is used as the keyword parameter # nil # nil Foo.splat({}) # (irb):23: warning: The last argument for `splat' (defined at (irb):16) is used as the keyword parameter # [] # nil Foo.options({ key: :value }) # (irb):24: warning: The last argument for `options' (defined at (irb):6) is used as the keyword parameter # nil # {:key=>:value} Foo.kwarg({ key: :value }) # (irb):25: warning: The last argument for `kwarg' (defined at (irb):11) is used as the keyword parameter # ArgumentError (unknown keyword: :key) Foo.splat({ key: :value }) # (irb):26: warning: The last argument for `splat' (defined at (irb):16) is used as the keyword parameter # ArgumentError (unknown keyword: :key) ``` In Ruby 3, the behavior will be: ```ruby Foo.options({}) # {} # {} Foo.kwarg({}) # {} # nil Foo.splat({}) # [{}] # nil Foo.options({ key: :value }) # {:key=>:value} # {} Foo.kwarg({ key: :value }) # {:key=>:value} # nil Foo.splat({ key: :value }) # [{:key=>:value}] # nil ``` I'm going to close this now as the deprecation warnings for the cases where behavior will change in Ruby 3 have been added. ---------------------------------------- Bug #12717: Optional argument treated as kwarg https://bugs.ruby-lang.org/issues/12717#change-81299 * Author: AMHOL (Andy Holland) * Status: Closed * Priority: Normal * Assignee: matz (Yukihiro Matsumoto) * Target version: * ruby -v: 2.3.1 * Backport: 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN ---------------------------------------- When you define a method with an optional argument and keyword arguments (whether explicitly or with options splat) the defaulted argument can not take a hash argument, instead it is interpreted as keyword arguments: ~~~ ruby class Foo def self.options(value = nil, **options) puts value.inspect puts options.inspect end def self.kwarg(value = nil, kw: nil) puts value.inspect puts kw.inspect end def self.splat(*args, kw: nil) puts args.inspect puts kw.inspect end end Foo.options({}) # nil # {} Foo.kwarg({}) # nil # nil Foo.splat({}) # [] # nil Foo.options({ key: :value }) # nil # {:key=>:value} Foo.kwarg({ key: :value }) # ArgumentError: unknown keyword: key Foo.splat({ key: :value }) # ArgumentError: unknown keyword: key ~~~ I would expect the output to be: ~~~ ruby Foo.options({}) # {} # {} Foo.kwarg({}) # {} # nil Foo.splat({}) # [{}] # nil Foo.options({ key: :value }) # {:key=>:value} # {} Foo.kwarg({ key: :value }) # {:key=>:value} # nil Foo.splat({ key: :value }) # [{:key=>:value}] # nil ~~~ -- https://bugs.ruby-lang.org/ Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe> <http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>