From: Zachary Scott Date: 2013-04-26T15:32:06+09:00 Subject: [ruby-core:54596] Re: [ruby-trunk - Bug #8040] Unexpect behavior when using keyword arguments --001a11c228be8e196c04db3db1a5 Content-Type: text/plain; charset=ISO-8859-1 Assign to nagachika-san On Apr 24, 2013 10:53 PM, "marcandre (Marc-Andre Lafortune)" < ruby-core@marc-andre.ca> wrote: > > Issue #8040 has been updated by marcandre (Marc-Andre Lafortune). > > > Any hope of getting this in time for next patchlevel release? > ---------------------------------------- > Bug #8040: Unexpect behavior when using keyword arguments > https://bugs.ruby-lang.org/issues/8040#change-38882 > > Author: pabloh (Pablo Herrero) > Status: Assigned > Priority: Normal > Assignee: mame (Yusuke Endoh) > Category: > Target version: > ruby -v: 2.0.0-p0 > Backport: > > > =begin > There is an odd behavior when calling methods with the new keyword > arguments syntax, when you have a method defined with mandatory arguments > that also takes options, like this: > > def foo value, **keywords > puts [value,keywords].inspect > end > > foo("somthing") #This works > foo("somthing", key: 'value') #This also works > > foo(Hash.new(something: 'else')) #This raises 'ArgumentError: wrong > number of arguments (0 for 1)' > > This feels weird regardless the fact that keyword arguments are a Hash at > the bottom, since you ARE PASSING an argument. > > Other side effect from this, is that when you call the method ((|foo|)) > with a single argument, you can't anticipate how many argument you will be > actually passing at runtime unless you know beforehand the argument's class. > > What's maybe even more concerning is the fact than this happens even when > you pass an argument which class derives from Hash: > > class MyDirectory < Hash; end > > foo(MyDirectory.new(something: 'else')) #This also raises > 'ArgumentError: wrong number of arguments (0 for 1)' > > > Besides finding this behavior surprising, I think this could also possibly > lead to old code been unexpectedly broken when updating old methods that > takes options to the new syntax. > > For example if you have this code: > > def foo_with_options argument, options = {} > #Do some stuff with options > end > > > #And at someplace else... > > my_hash_thingy = Hash.new > foo_with_options(my_hash_thingy) #Only passing mandatory argument, with > no options, works fine. > > > When updating to the new syntax: > > def foo_with_options argument, an_option: 'value1', another_option: > 'value2' > #Do some stuff with options > end > > > > #And at someplace else... > > my_hash_thingy = Hash.new > foo_with_options(my_hash_thingy) #Only passing mandatory argument, with > no options, doesn't work anymore. > =end > > > -- > http://bugs.ruby-lang.org/ > > --001a11c228be8e196c04db3db1a5 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable

Assign to nagachika-san

On Apr 24, 2013 10:53 PM, "marcandre (Marc-= Andre Lafortune)" <ruby-= core@marc-andre.ca> wrote:

Issue #8040 has been updated by marcandre (Marc-Andre Lafortune).


Any hope of getting this in time for next patchlevel release?
----------------------------------------
Bug #8040: Unexpect behavior when using keyword arguments
https://bugs.ruby-lang.org/issues/8040#change-38882

Author: pabloh (Pablo Herrero)
Status: Assigned
Priority: Normal
Assignee: mame (Yusuke Endoh)
Category:
Target version:
ruby -v: 2.0.0-p0
Backport:


=3Dbegin
There is an odd behavior when calling methods with the new keyword argument= s syntax, when you have a method defined with mandatory arguments that also= takes options, like this:

=A0 def foo value, **keywords
=A0 =A0 puts [value,keywords].inspect
=A0 end

=A0 foo("somthing") #This works
=A0 foo("somthing", key: 'value') #This also works

=A0 foo(Hash.new(something: 'else')) #This raises 'ArgumentErro= r: wrong number of arguments (0 for 1)'

This feels weird regardless the fact that keyword arguments are a Hash at t= he bottom, since you ARE PASSING an argument.

Other side effect from this, is that when you call the method ((|foo|)) wit= h a single argument, you can't anticipate how many argument you will be= actually passing at runtime unless you know beforehand the argument's = class.

What's maybe even more concerning is the fact than this happens even wh= en you pass an argument which class derives from Hash:

=A0 class MyDirectory < Hash; end

=A0 foo(MyDirectory.new(something: 'else')) #This also raises '= ArgumentError: wrong number of arguments (0 for 1)'


Besides finding this behavior surprising, I think this could also possibly = lead to old code been unexpectedly broken when updating old methods that ta= kes options to the new syntax.

For example if you have this code:

=A0 def foo_with_options argument, options =3D {}
=A0 =A0 #Do some stuff with options
=A0 end


=A0 #And at someplace else...

=A0 my_hash_thingy =3D Hash.new
=A0 foo_with_options(my_hash_thingy) #Only passing mandatory argument, with= no options, works fine.


When updating to the new syntax:

=A0 def foo_with_options argument, an_option: 'value1', another_opt= ion: 'value2'
=A0 =A0 #Do some stuff with options
=A0 end



=A0 #And at someplace else...

=A0 my_hash_thingy =3D Hash.new
=A0 foo_with_options(my_hash_thingy) #Only passing mandatory argument, with= no options, doesn't work anymore.
=3Dend


--
http://bugs.ruby-l= ang.org/

--001a11c228be8e196c04db3db1a5--