Project

General

Profile

ActionsLike0

Feature #14183

closed

"Real" keyword argument

Added by mame (Yusuke Endoh) over 7 years ago. Updated over 4 years ago.

Status:
Closed
Assignee:
-
Target version:
[ruby-core:84255]

Description

In RubyWorld Conference 2017 and RubyConf 2017, Matz officially said that Ruby 3.0 will have "real" keyword arguments. AFAIK there is no ticket about it, so I'm creating this (based on my understanding).

In Ruby 2, the keyword argument is a normal argument that is a Hash object (whose keys are all symbols) and is passed as the last argument. This design is chosen because of compatibility, but it is fairly complex, and has been a source of many corner cases where the behavior is not intuitive. (Some related tickets: #8040, #8316, #9898, #10856, #11236, #11967, #12104, #12717, #12821, #13336, #13647, #14130)

In Ruby 3, a keyword argument will be completely separated from normal arguments. (Like a block parameter that is also completely separated from normal arguments.)
This change will break compatibility; if you want to pass or accept keyword argument, you always need to use bare sym: val or double-splat ** syntax:

# The following calls pass keyword arguments
foo(..., key: val)
foo(..., **hsh)
foo(..., key: val, **hsh)

# The following calls pass **normal** arguments
foo(..., {key: val})
foo(..., hsh)
foo(..., {key: val, **hsh})

# The following method definitions accept keyword argument
def foo(..., key: val)
end
def foo(..., **hsh)
end

# The following method definitions accept **normal** argument
def foo(..., hsh)
end

In other words, the following programs WILL NOT work:

# This will cause an ArgumentError because the method foo does not accept keyword argument
def foo(a, b, c, hsh)
  p hsh[:key]
end
foo(1, 2, 3, key: 42)

# The following will work; you need to use keyword rest operator explicitly
def foo(a, b, c, **hsh)
  p hsh[:key]
end
foo(1, 2, 3, key: 42)

# This will cause an ArgumentError because the method call does not pass keyword argument
def foo(a, b, c, key: 1)
end
h = {key: 42}
foo(1, 2, 3, h)

# The following will work; you need to use keyword rest operator explicitly
def foo(a, b, c, key: 1)
end
h = {key: 42}
foo(1, 2, 3, **h)

I think here is a transition path:

  • Ruby 2.6 (or 2.7?) will output a warning when a normal argument is interpreted as keyword argument, or vice versa.
  • Ruby 3.0 will use the new semantics.

Files

vm_args.diff (4.19 KB) vm_args.diff jeremyevans0 (Jeremy Evans), 03/25/2019 10:48 PM
vm_args_v2.diff (4.18 KB) vm_args_v2.diff mame (Yusuke Endoh), 03/29/2019 10:29 AM

Related issues 22 (2 open20 closed)

Related to Ruby - Bug #8316: Can't pass hash to first positional argument; hash interpreted as keyword argumentsClosedmame (Yusuke Endoh)Actions
Related to Ruby - Bug #9898: Keyword argument odditiesClosed06/03/2014Actions
Related to Ruby - Bug #10856: Splat with empty keyword args gives unexpected resultsClosednobu (Nobuyoshi Nakada)Actions
Related to Ruby - Bug #11236: inconsistent behavior using ** vs hash as method parameterClosedActions
Related to Ruby - Bug #11967: Mixing kwargs with optional parameters changes way method parameters are parsedRejectedmatz (Yukihiro Matsumoto)Actions
Related to Ruby - Bug #12717: Optional argument treated as kwargClosedmatz (Yukihiro Matsumoto)Actions
Related to Ruby - Bug #12821: Object converted to Hash unexpectedly under certain method callClosedActions
Related to Ruby - Bug #13336: Default Parameters don't workClosedActions
Related to Ruby - Bug #13647: Some weird behaviour with keyword argumentsClosedmatz (Yukihiro Matsumoto)Actions
Related to Ruby - Bug #14130: Keyword arguments are ripped from the middle of hash if argument have default valueClosednobu (Nobuyoshi Nakada)Actions
Related to Ruby - Bug #15078: Hash splat of empty hash should not create a positional argument.Closedmatz (Yukihiro Matsumoto)Actions
Related to Ruby - Bug #14415: Empty keyword hashes get assigned to ordinal args.ClosedActions
Related to Ruby - Bug #12022: Inconsistent behavior with splatted named argumentsClosedActions
Related to Ruby - Bug #11860: Double splat does not work on empty hash assigned via variableClosedActions
Related to Ruby - Bug #10708: In a function call, double splat of an empty hash still calls the function with an argumentClosedmatz (Yukihiro Matsumoto)Actions
Related to Ruby - Bug #11068: unable to ommit an optional keyarg if the previous arg is an optional hashClosedActions
Related to Ruby - Bug #11039: method_missing の *args 引数に symbol をキーにした hash だけを渡すと エラーとなるClosedActions
Related to Ruby - Bug #10994: Inconsistent behavior when mixing optional argument and keyword splatClosedActions
Related to Ruby - Bug #10293: splatting an empty hash in a method invocation sends an argument to the method (should send nothing)Closednobu (Nobuyoshi Nakada)Actions
Related to Ruby - Bug #15753: unknown keyword when passing an hash to a method that accepts a default argument and a named argumentClosedActions
Related to Ruby - Misc #16188: What are the performance implications of the new keyword arguments in 2.7 and 3.0?Assignedjeremyevans0 (Jeremy Evans)Actions
Related to Ruby - Misc #16157: What is the correct and *portable* way to do generic delegation?OpenActions
#2

Updated by hsbt (Hiroshi SHIBATA) over 7 years ago

  • Related to Bug #8316: Can't pass hash to first positional argument; hash interpreted as keyword arguments added
#3

Updated by hsbt (Hiroshi SHIBATA) over 7 years ago

  • Related to Bug #9898: Keyword argument oddities added
#4

Updated by hsbt (Hiroshi SHIBATA) over 7 years ago

  • Related to Bug #10856: Splat with empty keyword args gives unexpected results added
#5

Updated by hsbt (Hiroshi SHIBATA) over 7 years ago

  • Related to Bug #11236: inconsistent behavior using ** vs hash as method parameter added
#6

Updated by hsbt (Hiroshi SHIBATA) over 7 years ago

  • Related to Bug #11967: Mixing kwargs with optional parameters changes way method parameters are parsed added
#7

Updated by hsbt (Hiroshi SHIBATA) over 7 years ago

  • Related to Bug #12104: Procs keyword arguments affect value of previous argument added
#8

Updated by hsbt (Hiroshi SHIBATA) over 7 years ago

  • Related to Bug #12717: Optional argument treated as kwarg added
#9

Updated by hsbt (Hiroshi SHIBATA) over 7 years ago

  • Related to Bug #12821: Object converted to Hash unexpectedly under certain method call added
#10

Updated by hsbt (Hiroshi SHIBATA) over 7 years ago

  • Related to Bug #13336: Default Parameters don't work added
#11

Updated by hsbt (Hiroshi SHIBATA) over 7 years ago

  • Related to Bug #13647: Some weird behaviour with keyword arguments added
#12

Updated by hsbt (Hiroshi SHIBATA) over 7 years ago

  • Related to Bug #14130: Keyword arguments are ripped from the middle of hash if argument have default value added
#14

Updated by mame (Yusuke Endoh) over 7 years ago

  • Tracker changed from Bug to Feature
  • Backport deleted (2.3: UNKNOWN, 2.4: UNKNOWN)
#17

Updated by mame (Yusuke Endoh) almost 7 years ago

  • Description updated (diff)
#36

Updated by marcandre (Marc-Andre Lafortune) over 6 years ago

  • Related to deleted (Bug #12104: Procs keyword arguments affect value of previous argument)
#39

Updated by mame (Yusuke Endoh) over 6 years ago

  • Related to Bug #15078: Hash splat of empty hash should not create a positional argument. added

Updated by jeremyevans0 (Jeremy Evans) about 6 years ago

Updated by mame (Yusuke Endoh) about 6 years ago

#64

Updated by jeremyevans0 (Jeremy Evans) almost 6 years ago

  • Related to Bug #14415: Empty keyword hashes get assigned to ordinal args. added
#65

Updated by jeremyevans0 (Jeremy Evans) almost 6 years ago

  • Related to Bug #12022: Inconsistent behavior with splatted named arguments added
#66

Updated by jeremyevans0 (Jeremy Evans) almost 6 years ago

  • Related to Bug #11860: Double splat does not work on empty hash assigned via variable added
#67

Updated by jeremyevans0 (Jeremy Evans) almost 6 years ago

  • Related to Bug #10708: In a function call, double splat of an empty hash still calls the function with an argument added
#69

Updated by jeremyevans0 (Jeremy Evans) almost 6 years ago

  • Related to Bug #11068: unable to ommit an optional keyarg if the previous arg is an optional hash added
#70

Updated by jeremyevans0 (Jeremy Evans) almost 6 years ago

  • Related to Bug #11039: method_missing の *args 引数に symbol をキーにした hash だけを渡すと エラーとなる added
#71

Updated by jeremyevans0 (Jeremy Evans) almost 6 years ago

  • Related to Bug #10994: Inconsistent behavior when mixing optional argument and keyword splat added
#81

Updated by jeremyevans0 (Jeremy Evans) over 5 years ago

  • Related to Bug #10293: splatting an empty hash in a method invocation sends an argument to the method (should send nothing) added

Updated by jeremyevans0 (Jeremy Evans) over 5 years ago

  • Status changed from Open to Closed
#86

Updated by jeremyevans0 (Jeremy Evans) over 5 years ago

  • Related to Bug #15753: unknown keyword when passing an hash to a method that accepts a default argument and a named argument added
#92

Updated by Eregon (Benoit Daloze) over 5 years ago

  • Related to Misc #16188: What are the performance implications of the new keyword arguments in 2.7 and 3.0? added
#93

Updated by Eregon (Benoit Daloze) over 5 years ago

  • Related to Misc #16157: What is the correct and *portable* way to do generic delegation? added
#117

Updated by nobu (Nobuyoshi Nakada) over 5 years ago

  • Target version changed from 3.0 to 36
#118

Updated by hsbt (Hiroshi SHIBATA) over 4 years ago

  • Target version changed from 36 to 3.0
ActionsLike0

Also available in: Atom PDF