Issue #7701 has been updated by headius (Charles Nutter).


trans (Thomas Sawyer) wrote:
> > trans: Modifying what #parameters returns is out of scope for this discussion. It already returns arrays of arrays of symbols, and changing it now would break backward compatibility.
> 
> Why should be out of scope? If you design to the limitation of what you have then what you get will be likewise limited.

Because the format of #parameters has very little to do with providing a required keyword argument feature. It does not move the discussion about required keyword arguments forward when we discuss new data formats for #parameters. Please stay on topic :-)

> It doesn't really matter though. The format of Method#parameter's output doesn't have to change to take into account a required default. I suppose you want something (sadly esoteric) like:
> 
>   def foo(a, b: required); end
>   method(:foo).parameters 
>   => [[:req, :a], [:reqkey, :b]]
> 
> Surely that's possible.

This was already suggested by multiple folks earlier in this issue. It's probably going to be :keyreq (along with :keyrest) but otherwise I consider the #parameters question solved.

> But besides all that, you haven't really addressed my points. To say "the original justification for adding required keyword arguments was so you didn't have to put your own error handling everywhere" just begs the question. You shouldn't be doing that either. I think the perceived advantage is rather illusory in real code and more commonly will be detrimental, not beneficial. And I've cited some reasons why I think that is so.

It seems a little early to claim that API designers "shouldn't" be doing something with keyword args (like requiring they be passed in) given that Ruby's only had keyword arguments for a couple weeks. It seems your only justification for rejecting required kwargs is because you believe it will be harder to remember required keywords than required positional arguments. Is that correct?

Honestly, this argument would have to work for optional keyword arguments if you want it to work for required keyword arguments. In order to make use of an API that has optional keyword arguments, you're *also* going to need to be looking at the docs and remembering the accepted keywords, their spelling, and so on. The only thing different about required keyword arguments is that you'll get an error if you forget a required kwarg, which is arguably providing *more* information and better hints for the user to fix their code. Imagine...

def foo(a:, b:) .... end

foo(1) => ArgumentError("Method `foo' requires arguments `a', `b'")

Bad thing?
----------------------------------------
Feature #7701: Non-optional (required) keyword args
https://bugs.ruby-lang.org/issues/7701#change-37545

Author: headius (Charles Nutter)
Status: Assigned
Priority: Normal
Assignee: nobu (Nobuyoshi Nakada)
Category: 
Target version: 


=begin
I would like to see keyword args expanded to include a non-optional form, to force callers to pass in keyword arguments.

Currently, we have required, optional, and rest positional args but only optional and rest keyword args. Consistency is one small reason to add required keyword args.

They would likely take the form of keyword with no default value:

  def foo(a:, b:)
    ...
  end

  foo(a: 1, b: 2) # ok
  foo(a: 1) # ArgumentError

Justifications:

* Consistency with positional args. A weak justification, I know.
* Avoiding a lot of boilerplate code by users wishing to enforce keywords being passed in. Example from tenderlove:

    def foo(a: raise('pass a'), b: raise('pass b'))

* Building a rich API atop keyword args would be easier (i.e. require fewer manual checks) if you could force some keywords to be passed in. Having to check everywhere when you require a keyword argument is unpleasant.
* Keyword args already enforces that no *additional* keyword args can be passed (without **), and it seems lopsided to have no way to enforce a minimum set of keyword args.
=end



-- 
http://bugs.ruby-lang.org/