https://redmine.ruby-lang.org/https://redmine.ruby-lang.org/favicon.ico?17113305112017-12-14T07:25:40ZRuby Issue Tracking SystemRuby master - Bug #14130: Keyword arguments are ripped from the middle of hash if argument have default valuehttps://redmine.ruby-lang.org/issues/14130?journal_id=684052017-12-14T07:25:40Zhsbt (Hiroshi SHIBATA)hsbt@ruby-lang.org
<ul><li><strong>Related to</strong> <i><a class="issue tracker-2 status-5 priority-4 priority-default closed" href="/issues/14183">Feature #14183</a>: "Real" keyword argument</i> added</li></ul> Ruby master - Bug #14130: Keyword arguments are ripped from the middle of hash if argument have default valuehttps://redmine.ruby-lang.org/issues/14130?journal_id=739072018-09-05T15:44:34Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<ul><li><strong>Assignee</strong> set to <i>nobu (Nobuyoshi Nakada)</i></li></ul><p>This is a bug.</p>
<pre><code>test1('River name' => 'Mississippi', length: 2000, 'Country' => 'USA')
# 3. SOURCE: {"River name"=>"Mississippi", "Country"=>"USA"}, OPTS: {:length=>2000} -- It is already a bit weird
</code></pre>
<p>My understanding is that under no circumstance should a mixed hash be split in two like this.</p>
<p>Ruby should recognize that some keys are no symbols and thus this hash can't be a keyword parameter hash and must be a positional argument. The correct result should thus be:</p>
<pre><code>SOURCE: {"River name"=>"Mississippi", :length=>2000, "Country"=>"USA"}, OPTS: {}
</code></pre>
<p>Note that this should still be true even if the <code>:length</code> key was the last one.</p>
<p>To obtain the current result, one would have to call <code>test1({'River name' => 'Mississippi', 'Country' => 'USA'}, length: 2000)</code></p> Ruby master - Bug #14130: Keyword arguments are ripped from the middle of hash if argument have default valuehttps://redmine.ruby-lang.org/issues/14130?journal_id=813012019-08-30T22:06:19Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul></ul><p>With the changes in <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: "Real" keyword argument (Closed)" href="https://redmine.ruby-lang.org/issues/14183">#14183</a>, keyword splats support non-symbol keys, so with the master branch you now get:</p>
<pre><code>No source
SOURCE: {}, OPTS: {:length=>2000}
SOURCE: {:length=>2000}, OPTS: {}
Source is mixed hash
SOURCE: {}, OPTS: {"River name"=>"Mississippi", :length=>2000, "Country"=>"USA"}
SOURCE: {"River name"=>"Mississippi", :length=>2000, "Country"=>"USA"}, OPTS: {}
</code></pre>
<p>In Ruby 3, you will get:</p>
<pre><code>No source
SOURCE: {}, OPTS: {:length=>2000}
# ArgumentError, because only keywords provided and no positional arguments, and at least one positional argument is required
Source is mixed hash
SOURCE: {}, OPTS: {"River name"=>"Mississippi", :length=>2000, "Country"=>"USA"}
# ArgumentError, because only keywords provided and no positional arguments, and at least one positional argument is required
</code></pre>
<p>This shows there is still work do to in 2.7 to warn cases where the behavior will change in Ruby 3. In both cases, the calls to <code>test2</code> should emit a warning, because the method will raise an error in Ruby 3.</p> Ruby master - Bug #14130: Keyword arguments are ripped from the middle of hash if argument have default valuehttps://redmine.ruby-lang.org/issues/14130?journal_id=813022019-08-30T23:25:55Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul></ul><p><a class="user active user-mention" href="https://redmine.ruby-lang.org/users/1604">@jeremyevans0 (Jeremy Evans)</a> Completely agreed.</p>
<p>Matz says that it is a bug to split keywords depending upon whether the key is Symbol or non-Symbol. (The behavior was introduced without matz's confirmation.) So I think it is okay that the behavior of Ruby 2.7 slightly changes.</p> Ruby master - Bug #14130: Keyword arguments are ripped from the middle of hash if argument have default valuehttps://redmine.ruby-lang.org/issues/14130?journal_id=813062019-08-31T02:46:12Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Closed</i></li></ul><p>With <a href="https://github.com/ruby/ruby/commit/3463e83192215c36bdcebad8be907eaa09593a41" class="external">https://github.com/ruby/ruby/commit/3463e83192215c36bdcebad8be907eaa09593a41</a>, you now get warnings for calls where the behavior will change in Ruby 3:</p>
<pre><code>No source
SOURCE: {}, OPTS: {:length=>2000}
file.rb:12: warning: The keyword argument for `test2' (defined at file.rb:5) is passed as the last hash parameter
SOURCE: {:length=>2000}, OPTS: {}
Source is mixed hash
SOURCE: {}, OPTS: {"River name"=>"Mississippi", :length=>2000, "Country"=>"USA"}
file.rb:19: warning: The keyword argument for `test2' (defined at file.rb:5) is passed as the last hash parameter
SOURCE: {"River name"=>"Mississippi", :length=>2000, "Country"=>"USA"}, OPTS: {}
</code></pre>