News for hackers. Stuff that matters.
Re:Ask HN: What does Ruby have that Python doesn't? by ubernostrum on Saturday August 23, 2008 @02:38AM (#284510)
His example is too incomplete to translate properly (since I don't know the details of other stuff he's referencing), but the basic idea is this:

A callable object in Python (e.g., a function or method, though not necessarily limited to these) can take advantage of two special options in declaring its argument signature. One is a feature shared between Python and Ruby: you can prefix the final argument with a single asterisk, which will be interpreted as "accept any number of additional positional arguments, and store them as a list in a variable of this name".

So, for example:

    def print_args(*args):
        for arg in args:
            print arg
Which does pretty much what it looks like it should do; you pass any number of arguments, and it echoes them back, each argument printed on a separate line.

The other part is something Ruby doesn't really support, because Ruby doesn't have a true analogue of Python's keyword arguments: using a double asterisk says, essentially, "accept any number of keyword arguments, and store them as a key/value mapping in a variable of this name".

So, for example:

    def print_keyword_args(**kwargs):
        for key, value in kwargs.items():
            print "%s: %s" % (key, value)
If you then did, say, `print_keyword_args(name='Bob', email='[email protected]')`, you'd get back the output (ordering of items may vary with the Python implementation, but usually you're not concerned with ordering -- that's what positional arguments are for):

    name: Bob
    email: [email protected]
These can also be combined into a standard idiom for a callable which accepts any combination of any number of named and keyword arguments:

    def takes_any_arguments(*args, **kwargs):
        ...
These sorts of idioms are incredibly useful for dynamic programming; for example, I work with (and help develop) the Django web framework, and our object-relational mapper uses the `kwargs` idiom to set up query methods which dynamically adapt the arguments they accept to the particular data model you're querying against.

There are no comments on this comment yet.