NAME

Acme::Pythonic - Python whitespace conventions for Perl

SYNOPSIS

use Acme::Pythonic; # this semicolon yet needed

for my $n in 1..1000:
    while $n != 1:
        if $n % 2:
            $n = 3*$n + 1
        else:
            $n /= 2

DESCRIPTION

Acme::Pythonic is a source filter that brings Python whitespace conventions to Perl.

This module is thought for those who embrace contradictions. It is an aid for those who are in an intermediate level, walking the Whitespace Matters Way in their pursuit of highest realization, only attained with SuperPython.

Labels

Labels are supported. This is the Acme::Pythonic version of the example in perlsyn:

OUTER: for my $wid in @ary1:
    INNER: for my $jet in @ary2:
        next OUTER if $wid > $jet
        $wid += $jet

Labeled blocks work as well:

my $k = 7
FOO:
    --$k
    last FOO if $k < 0
    redo FOO

Note that if we put a label in the line before in a control structure indentation matters. This would be a non-equivalent reformat of the example above:

OUTER:
    for my $wid in @ary1:               # NOT WHAT WE WANT
        INNER:
        for my $jet in @ary2:           # GOOD, ALIGNED
            next OUTER if $wid > $jet
            $wid += $jet

Since the first for is indented with respect to OUTER: we get a labeled block containing a for loop, instead of a labeled for.

Labels can be composed just of upper-case letters. That was decided so that list operators can be chained:

my @st = map:
             $_->[0]
         sort:
             $a->[1] <=> $b->[1]
         map:
             [$_, $foo{$_}]
         keys %foo

and &-prototyped subroutines can be used like this:

sub mygrep (&@):
    my $code = shift
    my @result
    foreach @_:
        push @result, $_ if &$code;
    return @result;

@array = mygrep:
             my $aux = $_
             $aux *= 3
             $aux += 1
             $aux % 2
         reverse 0..5

as long as the rightmost parameter is not of type &.

do/while-like constructs

Acme::Pythonic tries to detect loop modifiers after a do BLOCK. Thus

do:
    do_something()
    do_something_else()
while $condition

is seen as a do/while, whereas

do:
    do_something()
    do_something_else()
while $condition:
    handle_some_stuff()

is not.

New Keywords

pass

To be able to have an empty block we provide pass:

sub abstract_method:
    pass

in

This works:

foreach my $foo @array:
    do_something_with $foo

However in is supported in case you find the following more readable

foreach my $foo in @array:
    do_something_with $foo

This keyword can be used if there's no variable to its left too, which means we are dealing with $_ as usual:

foreach in @array:
    s/foo/bar/

but can't be used when the loop acts as a modifier:

print foreach in @array # ERROR

Continuation lines

As in Python, you can break a logical line in several physical lines using a backslash at the end:

my $total = total_products() + \
            total_delivery() + \
            total_taxes()

and in that case the indentation of those additional lines is irrelevant.

Ending commas

If a line ends in a comma or arrow (=>) it is joined with the following. This way we support

my %authors = (Perl   => "Larry Wall",
               Python => "Guido van Rossum")

which works in Python as well.

LIMITATIONS

Keywords followed by code in the same line are not supported. This would be valid in Python:

if $n % 2: $n = 3*$n + 1
else: $n /= 2

but it does not work in Acme::Pythonic.

DEBUG

You can pass a debug flag to Acme::Pythonic like this:

use Acme::Pythonic debug => 1;

In debug mode the module prints to standard output the code it has generated and substitutes everything with a dummy 1;, so nothing gets executed. This way the resulting source can be inspected.

This happens before Filter::Simple undoes the blanking out of PODs, strings, and regexps. Thus, those parts will be seen as $;s in a row ($; is \034 by default.)

BUGS

This module uses a regexp approach and the superb help of Filter::Simple. The regexp part of this means it is broken from the start, though I've tried hard to make it as robust as I could. Bug reports will be very welcome, just drop me a line!

THANKS

Damian Conway gave his full blessing if I wanted to write a module like this based on his unpublished Language::Pythonesque. The code that handles indentation is inspired by his.

Also, Dr. Conway is the author of Filter::Simple, which aids a lot blanking out PODs, strings, etc. so you can munge the source with certain confidence. Without Filter::Simple this module would be infinitely more broken.

SEE ALSO

perlfilter, Filter::Simple, SuperPython.

AUTHOR

Xavier Noria (FXN), <fxn@cpan.org>

COPYRIGHT AND LICENSE

Copyright (C) 2004 by Xavier Noria

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.2 or, at your option, any later version of Perl 5 you may have available.