ruby-changes:58108
From: Jeremy <ko1@a...>
Date: Fri, 4 Oct 2019 06:13:48 +0900 (JST)
Subject: [ruby-changes:58108] c7715a4936 (master): Add documentation regarding keyword argument separation [ci skip]
https://git.ruby-lang.org/ruby.git/commit/?id=c7715a4936 From c7715a4936a298ff9bcce97e65dfd3dc6f32f906 Mon Sep 17 00:00:00 2001 From: Jeremy Evans <code@j...> Date: Thu, 3 Oct 2019 13:14:45 -0700 Subject: Add documentation regarding keyword argument separation [ci skip] diff --git a/doc/syntax/calling_methods.rdoc b/doc/syntax/calling_methods.rdoc index ea2c49c..5abecc6 100644 --- a/doc/syntax/calling_methods.rdoc +++ b/doc/syntax/calling_methods.rdoc @@ -279,6 +279,9 @@ hash at the end of the array into keyword arguments: https://github.com/ruby/ruby/blob/trunk/doc/syntax/calling_methods.rdoc#L279 arguments = [1, 2, { c: 4 }] my_method(*arguments) +Note that this behavior is currently deprecated and will emit a warning. +This behavior will be removed in Ruby 3.0. + You may also use the <code>**</code> (described next) to convert a Hash into keyword arguments. @@ -325,7 +328,7 @@ by <code>*</code>: https://github.com/ruby/ruby/blob/trunk/doc/syntax/calling_methods.rdoc#L328 Prints: - {:arguments=>[1, 2, {"3"=>4}], :keywords=>{:five=>6}} + {:arguments=>[1, 2], :keywords=>{'3'=>4, :five=>6}} === Proc to Block Conversion diff --git a/doc/syntax/methods.rdoc b/doc/syntax/methods.rdoc index b3cebe3..55feecc 100644 --- a/doc/syntax/methods.rdoc +++ b/doc/syntax/methods.rdoc @@ -436,6 +436,99 @@ for the keyword argument: https://github.com/ruby/ruby/blob/trunk/doc/syntax/methods.rdoc#L436 When mixing keyword arguments and positional arguments, all positional arguments must appear before any keyword arguments. +Also, note that <code>**</code> can be used to ignore keyword arguments: + + def ignore_keywords(**) + end + +To mark a method as accepting keywords, but not actually accepting +keywords, you can use the <code>**nil</code>: + + def no_keywords(**nil) + end + +Calling such a method with keywords or a non-empty keyword splat will +result in an ArgumentError. This syntax is supported so that keywords +can be added to the method later without affected backwards compatibility. + +=== Keyword and Positional Argument Separation + +Between Ruby 2.0 and 2.6, keyword and positional arguments were not +separated, and a keyword argument could be used as a positional argument +and vice-versa. In Ruby 3.0, keyword and positional arguments will +be separated if the method definition includes keyword arguments. +In Ruby 3.0, if the method definition does not include keyword arguments, +keyword arguments provided when calling the method will continue to be +treated as a final positional hash argument. + +Currently, the keyword and positional arguments are not separated, +but cases where behavior will change in Ruby 3.0 will result in a +warning being emitted. + +There are a few different types of keyword argument separation issues. + +==== Conversion of Hash to Keywords + +If a method is called with the hash, the hash could be treated as +keywords: + + def my_method(**keywords) + keywords + end + my_method({a: 1}) # {:a => 1} + +This occurs even if the hash could be an optional positional argument +or an element of a rest argument: + + def my_method(hash=nil, **keywords) + [hash, keywords] + end + my_method({a: 1}) # [nil, {:a => 1}] + + def my_method(*args, **keywords) + [args, keywords] + end + my_method({a: 1}) # [[], {:a => 1}] + +However, if the hash is needed for a mandatory positional argument, +it would not be treated as keywords: + + def my_method(hash, **keywords) + [hash, keywords] + end + my_method({a: 1}) # [{:a => 1}, {}] + +==== Conversion of Keywords to Positional Arguments + +If a method is called with keywords, but it is missing one +mandatory positional argument, the keywords are converted to +a hash and the hash used as the mandtory positional argument: + + def my_method(hash, **keywords) + [hash, keywords] + end + my_method(a: 1) # [{:a => 1}, {}] + +This is also true for empty keyword splats: + + kw = {} + my_method(**kw) # [{}, {}] + +==== Splitting of Positional Hashes or Keywords + +If a method definition accepts specific keywords and not arbitrary keywords, +keywords or a positional hash may be split if the hash includes both Symbol +keys and non-Symbol keys and the keywords or positional hash are not needed +as a mandatory positional argument. In this case, the non-Symbol keys are +separated into a positional argument hash, and the Symbol keys are used +as the keyword arguments: + + def my_method(hash=3, a: 4) + [hash, a] + end + my_method(a: 1, 'a' => 2) # [{"a"=>2}, 1] + my_method({a: 1, 'a' => 2}) # [{"a"=>2}, 1] + == Block Argument The block argument is indicated by <code>&</code> and must come last: -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/