Interesting talk on Python vs. Ruby and how he would like Python to have just a bit more syntactic flexibility.

Steve Howell showell30 at yahoo.com
Thu Feb 18 22:43:14 EST 2010


On Feb 18, 3:00 pm, Steven D'Aprano <st... at REMOVE-THIS-
cybersource.com.au> wrote:
> [...]
> You wouldn't name your functions:
>
> f01, f02, f03, f04, ... f99
>

Exactly.

> (say), unless you were trying to deliberately obfuscate your code.
> Anonymous functions are even more obfuscated than that. You can get away
> with it so long as you're only dealing with a few, in well-defined
> placed, but you wouldn't want to use them all over the place.
>

I have contributed to the confusion of this discussion by talking
about "anonymous functions," when the original context was "anonymous
blocks."  As I mentioned in an earlier response, most anonymous blocks
in Ruby are placed within outer functions, so they're not that hard to
locate in a traceback that provides only function names.  And, of
course, it is often the case that you host Ruby code on your own web
server, or that you distribute Ruby code without compressing it, in
which case you get a sane traceback that provides line numbers.

You actually use anonymous blocks in your own code, in a few, well-
defined places (generally loops).

These excerpts are taken from obfuscate.py:

            quotient = a//mm
            a, mm = mm, a%mm
            xx, x = x - quotient*xx, xx
            yy, y = y - quotient*yy, yy


            rail = it.next()  # The rail we add to.
            assert 0 <= rail < rails
            fence[rail].append(c)


                # Save one non-chaff character.
                buffer.append(msg.next())
                # And toss away more chaff.
                n = self.hash(key) % factor
                key = self.mod_key(key)
                self.get_chars(n, msg)


            # Careful here! Not all classes have a __dict__!
            adict = getattr(obj, '__dict__', {})
            for name, attr in adict.items():
                if inspect.ismethoddescriptor(attr):
                    d[nm + '.' + name] = attr.__get__(obj)

If any of the above code were to fail on a customer site, you'd
probably want to get line numbers in a traceback.  I'm guessing you
probably don't distribute your code in compressed form, and you
probably take care to make sure it works right in the first place, and
you probably have source control to help you pull up old versions of
your code.  I notice that you even have a __version__ identifier in
your source code, which users of your library could capture in their
tracebacks.  In other words, you probably use mostly the same
practices that I use, except that we seem to differ on the utility or
expressiveness or Ruby blocks, or maybe we're arguing at cross
purposes.



More information about the Python-list mailing list