From: "trans (Thomas Sawyer)" <transfire@...> Date: 2013-03-12T22:52:01+09:00 Subject: [ruby-core:53335] [CommonRuby - Feature #7701] Non-optional (required) keyword args Issue #7701 has been updated by trans (Thomas Sawyer). =begin @prijutme4ty I think using #send as an example is a bit deceiving b/c it's one of the most well recognized predicate-to-preposition relations in the English language. Take it out of typical "mail" context and we are no better off. To make what I am saying more clear, consider that there is nothing preventing the developer from defining #send as: def send(text, sender:, recipient:) So, in ((*real code*)), you ((*will*)) be looking at some file hidden far in a thirdparty gem, trying to understand what required keyword arguments you need to use. Thus the above use of required keywords gains us nothing over: def send(text, sender, recipient) except more typing on the caller side. We should be careful about adding additional verbiage to APIs. It comes at a cost. It may not always be easy to recollect the order of arguments, but it can also be just as, if not more, difficult to remember the correct keyword, not to mention how to correctly spell it, leaving code open to more "bug vectors" due to typos. =end ---------------------------------------- Feature #7701: Non-optional (required) keyword args https://bugs.ruby-lang.org/issues/7701#change-37532 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/