https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112013-03-10T17:30:08ZRuby Issue Tracking SystemBackport200 - Backport #8040: Unexpect behavior when using keyword argumentshttps://bugs.ruby-lang.org/issues/8040?journal_id=374512013-03-10T17:30:08Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Assigned</i></li><li><strong>Assignee</strong> set to <i>matz (Yukihiro Matsumoto)</i></li></ul><p>This is a duplicate of <a class="issue tracker-1 status-6 priority-4 priority-default closed" title="Bug: キーワード引数を使うと最後のほうの通常の引数にハッシュを渡せない? (Rejected)" href="https://bugs.ruby-lang.org/issues/7529">#7529</a> which was once rejected by matz. I translate his reason:</p>
<blockquote>
<p>Unfortunately, it is the spec; we cannot distinguish whether the hash is for a keyword or for just an argument.<br>
Please add {} at the last.</p>
</blockquote>
<p>But, it may be good that we consider the hash for a keyword <em>only when</em> the number of arguments is more than the expected mandatory parameters.</p>
<p>diff --git a/vm_insnhelper.c b/vm_insnhelper.c<br>
index 0c447aa..2432288 100644<br>
--- a/vm_insnhelper.c<br>
+++ b/vm_insnhelper.c<br>
@@ -1065,12 +1065,12 @@ vm_caller_setup_args(const rb_thread_t *th, rb_control_frame_t *cfp, rb_call_inf<br>
}</p>
<p>static inline int<br>
-vm_callee_setup_keyword_arg(const rb_iseq_t *iseq, int argc, VALUE *orig_argv, VALUE *kwd)<br>
+vm_callee_setup_keyword_arg(const rb_iseq_t *iseq, int argc, int m, VALUE *orig_argv, VALUE *kwd)<br>
{<br>
VALUE keyword_hash;<br>
int i, j;</p>
<ul>
<li>if (argc > 0 &&</li>
</ul>
<ul>
<li>
<p>if (argc > m &&<br>
!NIL_P(keyword_hash = rb_check_hash_type(orig_argv[argc-1]))) {<br>
argc--;<br>
keyword_hash = rb_hash_dup(keyword_hash);<br>
@@ -1109,7 +1109,7 @@ vm_callee_setup_arg_complex(rb_thread_t *th, rb_call_info_t *ci, const rb_iseq_t</p>
<p>/* keyword argument */<br>
if (iseq->arg_keyword != -1) {</p>
</li>
</ul>
<ul>
<li>argc = vm_callee_setup_keyword_arg(iseq, argc, orig_argv, &keyword_hash);</li>
</ul>
<ul>
<li>
<p>argc = vm_callee_setup_keyword_arg(iseq, argc, m, orig_argv, &keyword_hash);<br>
}</p>
<p>/* mandatory */<br>
@@ -2127,7 +2127,7 @@ vm_yield_setup_block_args(rb_thread_t *th, const rb_iseq_t * iseq,</p>
<p>/* keyword argument */<br>
if (iseq->arg_keyword != -1) {</p>
</li>
</ul>
<ul>
<li>argc = vm_callee_setup_keyword_arg(iseq, argc, argv, &keyword_hash);</li>
</ul>
<ul>
<li>
<p>argc = vm_callee_setup_keyword_arg(iseq, argc, m, argv, &keyword_hash);<br>
}</p>
<p>/*</p>
</li>
</ul>
<p>--<br>
Yusuke Endoh <a href="mailto:mame@tsg.ne.jp" class="email">mame@tsg.ne.jp</a></p> Backport200 - Backport #8040: Unexpect behavior when using keyword argumentshttps://bugs.ruby-lang.org/issues/8040?journal_id=374822013-03-11T10:41:58Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<ul></ul><p>mame (Yusuke Endoh) wrote:</p>
<blockquote>
<p>But, it may be good that we consider the hash for a keyword <em>only when</em> the number of arguments is more than the expected mandatory parameters.</p>
</blockquote>
<p>+1</p> Backport200 - Backport #8040: Unexpect behavior when using keyword argumentshttps://bugs.ruby-lang.org/issues/8040?journal_id=376852013-03-18T11:36:47Zpabloh (Pablo Herrero)pablodherrero@gmail.com
<ul></ul><p>I also like Yusuke's approach. Is it been considered?</p> Backport200 - Backport #8040: Unexpect behavior when using keyword argumentshttps://bugs.ruby-lang.org/issues/8040?journal_id=377032013-03-19T03:23:19ZAnonymous
<ul></ul><p>Matz: could you please confirm that mandatory arguments should be fulfilled<br>
before checking for hash argument to fulfill named parameters?</p>
<p>BTW, also asked on StackOverflow today:</p>
<p><a href="http://stackoverflow.com/questions/15480236/how-can-i-prevent-a-positional-argument-from-being-expanded-into-keyword-argumen" class="external">http://stackoverflow.com/questions/15480236/how-can-i-prevent-a-positional-argument-from-being-expanded-into-keyword-argumen</a><a href="http://stackoverflow.com/questions/15480236/how-can-i-prevent-a-positional-argument-from-being-expanded-into-keyword-argumen/15483828#15483828" class="external">http://stackoverflow.com/questions/15480236/how-can-i-prevent-a-positional-argument-from-being-expanded-into-keyword-argumen/15483828#15483828</a></p>
<p>On Sun, Mar 17, 2013 at 10:36 PM, pabloh (Pablo Herrero) <<br>
<a href="mailto:pablodherrero@gmail.com" class="email">pablodherrero@gmail.com</a>> wrote:</p>
<blockquote>
<p>Issue <a class="issue tracker-4 status-5 priority-4 priority-default closed" title="Backport: Unexpect behavior when using keyword arguments (Closed)" href="https://bugs.ruby-lang.org/issues/8040">#8040</a> has been updated by pabloh (Pablo Herrero).</p>
<p>I also like Yusuke's approach. Is it been considered?</p>
<hr>
<p>Bug <a class="issue tracker-4 status-5 priority-4 priority-default closed" title="Backport: Unexpect behavior when using keyword arguments (Closed)" href="https://bugs.ruby-lang.org/issues/8040">#8040</a>: Unexpect behavior when using keyword arguments<br>
<a href="https://bugs.ruby-lang.org/issues/8040#change-37685" class="external">https://bugs.ruby-lang.org/issues/8040#change-37685</a></p>
<p>Author: pabloh (Pablo Herrero)<br>
Status: Assigned<br>
Priority: Normal<br>
Assignee: matz (Yukihiro Matsumoto)<br>
Category:<br>
Target version:<br>
ruby -v: 2.0.0-p0</p>
<p>=begin<br>
There is an odd behavior when calling methods with the new keyword<br>
arguments syntax, when you have a method defined with mandatory arguments<br>
that also takes options, like this:</p>
<p>def foo value, **keywords<br>
puts [value,keywords].inspect<br>
end</p>
<p>foo("somthing") #This works<br>
foo("somthing", key: 'value') #This also works</p>
<p>foo(Hash.new(something: 'else')) #This raises 'ArgumentError: wrong<br>
number of arguments (0 for 1)'</p>
<p>This feels weird regardless the fact that keyword arguments are a Hash at<br>
the bottom, since you ARE PASSING an argument.</p>
<p>Other side effect from this, is that when you call the method ((|foo|))<br>
with a single argument, you can't anticipate how many argument you will be<br>
actually passing at runtime unless you know beforehand the argument's class.</p>
<p>What's maybe even more concerning is the fact than this happens even when<br>
you pass an argument which class derives from Hash:</p>
<p>class MyDirectory < Hash; end</p>
<p>foo(MyDirectory.new(something: 'else')) #This also raises<br>
'ArgumentError: wrong number of arguments (0 for 1)'</p>
<p>Besides finding this behavior surprising, I think this could also possibly<br>
lead to old code been unexpectedly broken when updating old methods that<br>
takes options to the new syntax.</p>
<p>For example if you have this code:</p>
<p>def foo_with_options argument, options = {}<br>
#Do some stuff with options<br>
end</p>
<p>#And at someplace else...</p>
<p>my_hash_thingy = Hash.new<br>
foo_with_options(my_hash_thingy) #Only passing mandatory argument, with<br>
no options, works fine.</p>
<p>When updating to the new syntax:</p>
<p>def foo_with_options argument, an_option: 'value1', another_option:<br>
'value2'<br>
#Do some stuff with options<br>
end</p>
<p>#And at someplace else...</p>
<p>my_hash_thingy = Hash.new<br>
foo_with_options(my_hash_thingy) #Only passing mandatory argument, with<br>
no options, doesn't work anymore.<br>
=end</p>
<p>--<br>
<a href="http://bugs.ruby-lang.org/" class="external">http://bugs.ruby-lang.org/</a></p>
</blockquote> Backport200 - Backport #8040: Unexpect behavior when using keyword argumentshttps://bugs.ruby-lang.org/issues/8040?journal_id=377092013-03-19T10:49:31Zmatz (Yukihiro Matsumoto)matz@ruby.or.jp
<ul><li><strong>Assignee</strong> changed from <i>matz (Yukihiro Matsumoto)</i> to <i>mame (Yusuke Endoh)</i></li></ul><p>Accepted. Prioritize mandatory argument sounds reasonable.</p>
<p>Matz.</p> Backport200 - Backport #8040: Unexpect behavior when using keyword argumentshttps://bugs.ruby-lang.org/issues/8040?journal_id=384022013-04-10T02:32:45Zpabloh (Pablo Herrero)pablodherrero@gmail.com
<ul></ul><p>Any news about this?</p> Backport200 - Backport #8040: Unexpect behavior when using keyword argumentshttps://bugs.ruby-lang.org/issues/8040?journal_id=388822013-04-25T11:52:06Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<ul></ul><p>Any hope of getting this in time for next patchlevel release?</p> Backport200 - Backport #8040: Unexpect behavior when using keyword argumentshttps://bugs.ruby-lang.org/issues/8040?journal_id=389182013-04-26T15:53:17Zzzak (zzak _)
<ul></ul><p>Assign to nagachika-san</p> Backport200 - Backport #8040: Unexpect behavior when using keyword argumentshttps://bugs.ruby-lang.org/issues/8040?journal_id=391652013-05-06T22:32:24Znagachika (Tomoyuki Chikanaga)nagachika00@gmail.com
<ul></ul><p>ping?</p> Backport200 - Backport #8040: Unexpect behavior when using keyword argumentshttps://bugs.ruby-lang.org/issues/8040?journal_id=395662013-05-30T19:50:44Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Assigned</i> to <i>Closed</i></li><li><strong>% Done</strong> changed from <i>0</i> to <i>100</i></li></ul><p>This issue was solved with changeset r40992.<br>
Pablo, thank you for reporting this issue.<br>
Your contribution to Ruby is greatly appreciated.<br>
May Ruby be with you.</p>
<hr>
<ul>
<li>
<p>vm_insnhelper.c (vm_callee_setup_keyword_arg,<br>
vm_callee_setup_arg_complex): consider a hash argument for keyword<br>
only when the number of arguments is more than the expected<br>
mandatory parameters. <a href="/issues/8040">[ruby-core:53199]</a> [ruby-trunk - Bug <a class="issue tracker-4 status-5 priority-4 priority-default closed" title="Backport: Unexpect behavior when using keyword arguments (Closed)" href="https://bugs.ruby-lang.org/issues/8040">#8040</a>]</p>
</li>
<li>
<p>test/ruby/test_keyword.rb: update a test for above.</p>
</li>
</ul> Backport200 - Backport #8040: Unexpect behavior when using keyword argumentshttps://bugs.ruby-lang.org/issues/8040?journal_id=395672013-05-30T19:52:34Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul><li><strong>Tracker</strong> changed from <i>Bug</i> to <i>Backport</i></li><li><strong>Project</strong> changed from <i>Ruby master</i> to <i>Backport200</i></li><li><strong>Status</strong> changed from <i>Closed</i> to <i>Assigned</i></li><li><strong>Assignee</strong> changed from <i>mame (Yusuke Endoh)</i> to <i>nagachika (Tomoyuki Chikanaga)</i></li></ul><p>Fixed. Sorry for very very late action!<br>
I left to nagachika-san whether it should be backported or not.</p>
<p>--<br>
Yusuke Endoh <a href="mailto:mame@tsg.ne.jp" class="email">mame@tsg.ne.jp</a></p> Backport200 - Backport #8040: Unexpect behavior when using keyword argumentshttps://bugs.ruby-lang.org/issues/8040?journal_id=395692013-05-30T22:37:51Znagachika (Tomoyuki Chikanaga)nagachika00@gmail.com
<ul><li><strong>Priority</strong> changed from <i>Normal</i> to <i>5</i></li></ul><p>I also think new behavior is better than former behavior.<br>
I'll backport it till next release.</p> Backport200 - Backport #8040: Unexpect behavior when using keyword argumentshttps://bugs.ruby-lang.org/issues/8040?journal_id=396922013-06-04T23:30:32Znagachika (Tomoyuki Chikanaga)nagachika00@gmail.com
<ul><li><strong>Status</strong> changed from <i>Assigned</i> to <i>Closed</i></li></ul><p>This issue was solved with changeset r41063.<br>
Pablo, thank you for reporting this issue.<br>
Your contribution to Ruby is greatly appreciated.<br>
May Ruby be with you.</p>
<hr>
<p>merge revision(s) 40992: [Backport <a class="issue tracker-4 status-5 priority-4 priority-default closed" title="Backport: Unexpect behavior when using keyword arguments (Closed)" href="https://bugs.ruby-lang.org/issues/8040">#8040</a>]</p>
<pre><code>* 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. <a href="/issues/8040">[ruby-core:53199]</a> [ruby-trunk - Bug #8040]
* test/ruby/test_keyword.rb: update a test for above.
</code></pre> Backport200 - Backport #8040: Unexpect behavior when using keyword argumentshttps://bugs.ruby-lang.org/issues/8040?journal_id=683832017-12-14T07:23:44Zhsbt (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>