Ruby Impressions

Adam Spitz adamspitz at bigfoot.com
Sat Jan 12 01:11:53 EST 2002


Paul Rubin wrote:

> I think you could do something like it with python 2.2 metaclasses,
> but it would confuse the hell out of people.  However Python doesn't
> make you use separate symbols for arrays and non-arrays, so it's 
> probably reasonable to just leave things the way they are.

I don't understand what you mean. Ruby doesn't do that either. The @
signs make a lot of Python people run screaming (and I understand why
- Perl makes me run screaming, too ;), but semantically, Ruby is a lot
closer to Python than it is to Perl.

@varname in Ruby is equivalent to self.varname in Python. That's just
how you name instance variables. It is absolutely totally completely
different from the way Perl uses punctuation to distinguish between
scalars and lists. Ruby doesn't do anything like that. I promise. :)

But I suppose my original post wasn't very clear. Here's the problem
that we were solving:

class Person:
    def __init__(self, name, age, gender):
        self.name, self.age, self.gender = name, age, gender
        self.doSomeStuff()

A lot of my __init__ methods look like that: they take a few
parameters, store them as attributes, and then maybe do some more
stuff. Every single time I do this, I have to write out the parameter
list three times - once in the method signature, once on the left side
of the equals sign, and once on the right side of the equals sign.

I'd like to be able to tell Python, "Make me an __init__ method that
takes these three parameters, stores them as attributes, and then does
this other stuff." And I'd like to be able to do it in a way that
doesn't force me to repeat the parameter list three times. Ideally,
it'd look something like this (if I were allowed to make up any syntax
I wanted):

class Person:
    init_attributes("name", "age", "gender"):
        self.doSomeStuff()

I can almost do it. Python is a reasonably flexible language, and we
found a couple of different ways to come close to what I wanted. (Take
a look at http://c2.com/cgi/wiki?PythonRubyInitializer.) I came up
with a version that used eval(), and the Python guys came up with a
more Pythonic version that used neato class tricks. But we couldn't
get a syntax more intuitive than this (with either version):

class Person:
    def __extra_init__(self):
        self.doSomeStuff()

init_attributes(Person, "name", "age", "gender")

You see? We can create an init_attributes method that generates the
__init__ method that we want, but we can't *call* the init_attributes
method until after the class has already been defined, which means
that we have to put it *underneath* the class definition, which is a
very unintuitive place to look for an initializer. So I'm pretty sure
that nobody would ever use this mechanism - and rightfully so, because
it would be a lot harder to understand than the normal way.

Ruby, though, is flexible enough to allow me to create a mechanism
that solves the problem in a way that's just as easy to understand as
the normal way. And so my life got a little bit happier. :)

By now, I'm sure most of you are thinking, "Who cares? Just write out
the __init__ method the normal way. It's not so bad." And you're
right. It's really not a big deal. In fact, forget that I said
anything. Python is good enough. Really.


Adam Spitz



More information about the Python-list mailing list