Matz: could you please confirm that mandatory arguments should be fulfilled
before checking for hash argument to fulfill named parameters?

BTW, also asked on StackOverflow today:

http://stackoverflow.com/questions/15480236/how-can-i-prevent-a-positional-=
argument-from-being-expanded-into-keyword-argumen<http://stackoverflow.com/=
questions/15480236/how-can-i-prevent-a-positional-argument-from-being-expan=
ded-into-keyword-argumen/15483828#15483828>


On Sun, Mar 17, 2013 at 10:36 PM, pabloh (Pablo Herrero) <
pablodherrero / gmail.com> wrote:

>
> Issue #8040 has been updated by pabloh (Pablo Herrero).
>
>
> I also like Yusuke's approach. Is it been considered?
>
> ----------------------------------------
> Bug #8040: Unexpect behavior when using keyword arguments
> https://bugs.ruby-lang.org/issues/8040#change-37685
>
> Author: pabloh (Pablo Herrero)
> Status: Assigned
> Priority: Normal
> Assignee: matz (Yukihiro Matsumoto)
> Category:
> Target version:
> ruby -v: 2.0.0-p0
>
>
> =3Dbegin
> 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 b=
e
> actually passing at runtime unless you know beforehand the argument's cla=
ss.
>
> 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 possibl=
y
> 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 =3D {}
>     #Do some stuff with options
>   end
>
>
>   #And at someplace else...
>
>   my_hash_thingy =3D 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 =3D Hash.new
>   foo_with_options(my_hash_thingy) #Only passing mandatory argument, with
> no options, doesn't work anymore.
> =3Dend
>
>
> --
> http://bugs.ruby-lang.org/
>
>