Hi,
On 23 October 2011 14:53, Yusuke Endoh <mame / tsg.ne.jp> wrote:
>
> Issue #5474 has been reported by Yusuke Endoh.
>
> ----------------------------------------
> Feature #5474: keyword argument
> http://redmine.ruby-lang.org/issues/5474
>
> Author: Yusuke Endoh
> Status: Assigned
> Priority: Normal
> Assignee: Koichi Sasada
> Category: core
> Target version:
>
>
> Hello,
>
> I'm sending a patch for keyword arguments.
>
> (This feature had been discussed in #5454, but I'm re-creating
>       >
>
> Matz himself proposed this feature.    > promised to include the feature in 2.0.  庳
> I'm planning to commit the patch after it is reviewed by koichi.
>
> But the detail of the spec is not fixed yet, and may be changed
> drastically.
> We would like to hear your comments and suggestions, especially,
> with a use case and/or an actual experience.
>
>
>
> The background of this proposal is that, in the recent Ruby,
> the last argument (as a Hash) is often used to pass optional
> information.     
>
> Look an example:
>
>     墬 屩
>  keyword arguments   >
>     >  
>
>  
> => [2, 3, "red", 1]
>
> The caller size is a traditional hash argument notation.
> This feature is Hash parsing in the callee side.
>
> (So it is more suitable to call it "keyword parameter."
>  
>
>
> We can implement the similar behavior in pure Ruby.  > this feature is easier to read/write, and richer in the some
> aspects:
>
> - it raises an TypeError when unknown keyword is given
>
>  
> => unknown keyword (TypeError)
>
> - you can use ** argument to suppress the TypeError and/or
>   >
>     墬 屬 
>     
>  
>  
> => [2, 3, "red", 1, {:style=>"solid"}]
>
> - it is easily used even when there is a rest argument
>
>     䢬 屩
> ..
>  
>
> a complex and non-essential code is required to
> implement the same behavior in pure Ruby)
>
> - there is room for optimizing the speed (though I have
>     
>
>
>
> An alternative design is to treat all parameters as keyword
> arguments (as Evan said in [ruby-core:40195]).
>
>  
>     >  
>  
> => [2, 3, "red", 1]
>
> Actually I also like this, but I'm afraid if it is too flexible
> and seems difficult to implement and optimize.
>
>
> Thanks,
>
> --
> Yusuke Endoh <mame / tsg.ne.jp>
>
>
> --
> http://redmine.ruby-lang.org
>
>

It sounds great!

I agree mandatory keyword arguments should be positional arguments and
  all parameters should not be treated as keyword arguments.

I have a few questions/remarks:
1) What is the way to pass keyword arguments ?
I would guess `**h` like:

def meth(a, **h)
  other(a, **h)
end # => syntax error

BTW, using **h in the argument list does not seems to work in some cases for me:

def a(**h)
end # => syntax error, unexpected tPOW

def m(k: nil, **h, &block)
end
m() # => undefined method `key?' for nil:NilClass

2) I'm a bit dubious about the `**h` syntax to get (and I guess to
pass) a Hash though.
I know it's the way it's done in Python, but I don't like it
(esthetically), especially when it is used to pass the Hash:

def meth(a, *r, **h)
  other(a, *r, **h)
end

I believe `*args` is appropriate for the rest argument, because the
star is the splat operator.
I cannot think of any clear logic like that for `**h` except "another
rest argument".
Also `**` is the power operator, which is unrelated.
Something related to `{}`, the literal Hash syntax, would fit better
in my opinion.

Do you have any idea of an alternate syntax to `**h` ?

(Or maybe we should introduce `a, b = **h` as a joke for `a, b =
h.values_at(:a, :b)`)

3) What would {Proc,Method,UnboundMethod}#parameters returns for
keywords arguments ?

def meth(mandatory, optional = nil, *rest, post, keyw: nil, **h, &block)
end
p method(:meth).parameters
Currently: [[:req, :mandatory], [:opt, :optional], [:rest, :rest],
[:req, :post], [:block, :block]]
Something like:
[[:req, :mandatory], [:opt, :optional], [:rest, :rest], [:req, :post],
[:key, :keyw], [:keyrest, :h], [:block, :block]] ?

4)  I noticed a few problems while experimenting:
def a(k: :a, **h)
  p [k,h]
end
a(:b, c: :d, e: :f) # => wrong number of arguments (2 for 0) (ArgumentError)
It should be "1 for 0"

def a(k: :a)
  p [k,h]
end
a(r: :a) # => unknown keyword (TypeError)
It should say which keyword is missing (and an ArgumentError rather
than TypeError, no?).

(Of course I do not expect the current patch to pass these details, I
just mention them to be sure they will be considered.)