Confessions of a Python fanboy

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Fri Jul 31 11:55:43 EDT 2009


On Fri, 31 Jul 2009 13:38:56 +0200, Bruno Desthuilliers wrote:

>> On the other hand, we don't have to prefix names with @ and @@,
> 
> Nope, we have to prefix them with 'self' or 'cls' (or even
> 'self.__class__').

Incorrect.

>>> class K:
...     class_attribute = 'No @@ required.'
...
>>> K().class_attribute
'No @@ required.'


No 'self' or 'cls' in sight.


I can see a vague advantage to using @ to create instance attributes and 
@@ to creating class attributes -- it makes it easy to create class 
attributes inside a method without needing to do a double lookup. In 
Python terms:

def K:
    def method(self):
        self.__class__.attr = "Class attribute"

would be:

def K:
    def method(self):
        @@attr = "Class attribute"

Advantages: you save a few characters and (possibly!) a couple of runtime 
lookups.

Disadvantages: your code is filled with line noise. It's an arbitrary 
choice between @@ meaning instance attribute and @@ meaning class 
attribute -- there's no logical reason for choosing one over the other, 
so you have to memorise which is which. It's easy to get it wrong.

'self' and 'cls' at least are words, even if 'cls' is badly misspelled :)



>> and we
>> don't have the compiler trying to *guess* whether we're calling a
>> function or referring to a variable.
> 
> Please re-read a bit more carefully - it's *all* method call. 

What did I misread from here?

[quote]
When Ruby sees a name such as ``a'' in an expression, it needs to 
determine if it is a local variable reference or a call to a method with 
no parameters. To decide which is the case, Ruby uses a heuristic. As 
Ruby reads a source file, it keeps track of symbols that have been 
assigned to. It assumes that these symbols are variables. When it 
subsequently comes across a symbol that might be either a variable or a 
method call, it checks to see if it has seen a prior assignment to that 
symbol. If so, it treats the symbol as a variable; otherwise it treats it 
as a method call.
[end quote]

And see the example "pathological case" comparing a function call (not 
method) and a variable.

http://ruby-doc.org/docs/ProgrammingRuby/html/language.html


> Python is
> 'uniform' in obj.name is always an attribute lookup (methods being
> attributes), Ruby is uniform in that 'obj.name' is always a method call.

Which would be relevant if I was talking about method calls, but I wasn't.



>> Somebody who knows more Ruby than me should try writing the Zen of
>> Ruby. Something like:
> 
> (snip childish parody of Python Zen)
> 
> Steven, is that any useful ?

It made me feel good.

But seriously, while I admit that I have very little Ruby experience, and 
so aren't in a great position to judge, it seems to me that Ruby doesn't 
have anything like Python's over-riding design principles (the Zen). If 
there is a design principle to Ruby, I can't see what it is.

I'm the first to admit that I'm far too inexperienced with the language 
to make this a fair judgement. Unfair it might be, but it doesn't 
necessarily mean I'm wrong! *wink*

Ruby just seems to be far more complicated than Python: things which 
Python does at runtime, with a function call, Ruby has special syntax for:

"a bunch of words".split()
%w(a bunch of words)

ord('a')
?a

That makes the barrier to entry far higher: it's easier to leverage 
existing knowledge to interpret unfamiliar Python code than unfamiliar 
Ruby code. Or so it seems to me.

Oh, and I admit that Python decorators are a conspicuous counter-example. 
I wouldn't do without them, but neither would I expect somebody to intuit 
what they do.


>> Although I'm sure Ruby has its good points. I'm not convinced anonymous
>> code blocks are one of them though.
> 
> Ruby's code blocks come from Smalltalk, where they are an absolute
> necessity since message passing (which code blocks are part of) is the
> *only* builtin control flow in Smalltalk - so you just *need* this
> construction to provide branching and iterations.

Just because Smalltalk had a particular (mis?)feature doesn't mean that 
other languages should copy it. I know, I know, Ruby people swear by 
anonymous code blocks, and I've read Paul Graham too. But I'm really not 
so sure that the benefits of anonymous code blocks are great enough to 
overcome the disadvantages of anonymous code blocks.


> Wether it makes sense to have code blocks in Ruby is another question
> since Ruby does provide traditional control flow features, but then one
> could question Python's "lambda" (hem...) too.

lambda, by allowing the function to be only a single expression, doesn't 
suffer the disadvantages of anonymous code blocks. lambda, by allowing 
the function to be only a single expression, also has fewer advantages 
than anonymous code blocks. I think lambda ends up on the "more 
advantages than disadvantages" side. I'm keeping my mind open regarding 
Ruby code blocks.



-- 
Steven



More information about the Python-list mailing list