Ruby Impressions

Kragen Sitaker kragen at
Tue Jan 29 18:33:42 CET 2002

"Andrew Dalke" <dalke at> writes:
> You could also parameterize the init_attributes function to call any
> function you may want, instead of 'initialize'.

Yes, but why?

> Another problem is that once you start this route you also start wanting
> variations.  Keyword parameters.  Optional parameters.  Default values.
> Range checking to a list of restricted values.  And more.

MetaPy (see or .zip)
includes an implementation of exactly such a thing, entitled
"defrecord", in about 40 or 50 lines of Python.  It supports keyword
parameters, optional parameters, and default values.  It doesn't
support range checking, and its argument handling isn't quite as
flexible as what Python provides for ordinary methods.

I wrote it for two reasons:
- I wanted to refactor code that was returning tuples to return class
  instances instead (PEP 42 wants this for some built-in functions, but
  I wanted it for some of my own)
- I had some data-container classes with no methods, and I was sick of writing
  their declarations.  I know that's not very object-oriented.  Shame on me.  

> Bingo!  And the reader won't know what it means without digging
> through the rest of the system.  And that poor soul won't know what
>   init_attributes( "name" = (None, ["Andrew", "Brandy", "Cindy", "Dylan"],
> None),
>                    "age" = (18, None, None),
>                    "gender" = (None, ["male", "female"], \
>                                    "Sorry, we're a bit old-fashioned
> here") )
> says that:
>   "name" can take one of four possible values
>   "age" can take any value, with a default value of 18
>   "gender" can take only two values, and if those values aren't used then
> the
>       error message for the TypeError exception is as given

That's mostly a problem with your poorly-designed interface (which
isn't legal Python syntax anyway).  If the reader understands

    Vikingtype = defrecord('spam', 'eggs', 'ham')

(for which they might need to read the docstring for defrecord), and
they understand how Python attribute inheritance works, then they can
probably figure out that

    Vikingtype = defrecord('spam', 'eggs', 'ham')
    Vikingtype.ham = "tasty"

does the same, but provides a default value for "ham" when it isn't

More information about the Python-list mailing list