djberg96 (djberg96) wrote,

  • Mood:

Better Keyword Arguments

One of the things Matz discussed during his keynote was keyword arguments for Ruby 2.0. His proposal went something like this:
def foo(a, b=0, c:4)

foo(1, 2, c:3) # a=1, b=2, c=3

I took an immediate dislike to this proposal. The first problem I have with it is that you're forced to make a declaration about How Things Work in the method definition. The second problem I have is that I'll be forced to lookup the method definition in order to see which parameters allow keyword arguments and which don't. That, or we'll need a major change to rdoc.

Things went from bad to worse with the *rest and **keyword syntax. Oofda.
def foo(*rest, a:4, b:0, **keys)

baz(1, 2, b:2) # rest=[1,2,{b:2}], a=4, b=2, keys={b:2}

This makes my head want to explode. It's a complete break from current Ruby syntax, looks like complete hell, and is utterly untuitive. It's just overwrought.

The ideal solution is to allow users to use keyword parameters without having to do anything special whatsovever in the method definition, and allowing keyword parameters to be used for all variables, in addition to allowing positional parameters:
# A standard Ruby method declaration
def foo(a, b, c=4)

# Ideal syntax
foo(a:1, b:2, c:3) # a=1, b=2, c=3
foo(c:3, a:1, b:2) # a=1, b=2, c=3
foo(a:1, b:2)      # a=1, b=2, c=4
foo(b:2, a:1)      # a=1, b=2, c=4
foo(1, 2, c:3)     # a=1, b=2, c=3
foo(1, 2, 3)       # a=1, b=2, c=3

As for *rest parameters, the ideal situation is to eliminate **keys altogether (yuck) and keep the current behavior where *rest arguments come at the end of the method declaration. For keyword parameters slurped into a *rest variable, they are collected as a hash:
def foo(a, b, *c)

foo(1, 2, 3)            # a=1, b=2, c=[3]
foo(1, 2, foo:4, bar:5) # a=1, b=2, c=[{'foo'=>4, 'bar'=>5}]
foo(1, 2, 8, baz:5)     # a=1, b=2, c=[8, {'baz'=>5}]

Clean. Sensical. No extra work in the method declaration. Keeps the current rules in effect with regards to *rest variables. None of that **keys nonsense. Even forces you to use good variable names for people reading the generated documentation who need to know what the valid parameters are.

Wouldn't that be awesome?

Now what if I told you that it's already in Sydney?


Update: I've added a couple more examples since I originally posted.

  • Running a remote rails console

    Another tip for myself, courtesy of a co-worker. If you want to run a rails console on a remote app you can use the `ssh -t` option. The -t option…

  • (no subject)

    Mostly a note to self, this is how you can show your current git branch in Windows Powershell. Just add it to your profile.ps1. function prompt{…

  • Building libxml2 and libxslt on Windows

    I had a little trouble building these from source with MSVC so I thought I'd record the issues I faced both so that I can refer back to this post…

  • Post a new comment


    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded