<?xml version="1.0" encoding="windows-1252"?>
<node id="266609" title="Mandatory indenting" created="2003-06-17 15:23:49" updated="2005-08-09 06:44:43">
<type id="120">
perlmeditation</type>
<author id="132236">
Juerd</author>
<data>
<field name="doctext">
&lt;p&gt;
In Python, a programming language that I don't like much, you don't use curly braces or keywords to delimit code blocks. Instead, indenting is required. The block ends when indenting ends.
&lt;/p&gt;
&lt;p&gt;
I hate forced indenting. Even though I always indent, I don't want this to be necessary - I want to code in my own style, and be able to change that style when I feel like doing so. This is the number one reason for me to not learn anything about Python.
&lt;/p&gt;
&lt;p&gt;
But apparently some people like forced indentation and some even use Python because of only that. Well, Perl can do this too. Let's start with an example script, that I will call &lt;tt&gt;test.pl&lt;/tt&gt;:
&lt;readmore&gt;
&lt;code&gt;
#!/usr/bin/perl -w
use strict;

$a = 0;

while ($a &lt; 5) {
    print ++$a, "\n";
    for $b (1..10) {
        print "$a $b\n";
    }
    for $b (11, 12) {
        print "$a $b\n";
    }
}

print "done\n";
&lt;/code&gt;
&lt;small&gt;(Yes, this does use package globals, yes, strict is kind of useless because of that. I just typed "use strict;" because it's a habit. A good one, IMO.)&lt;/small&gt;
&lt;/readmore&gt;
&lt;/p&gt;
&lt;p&gt;
Now let's remove the curlies, since when I'm done, they will be inserted automatically.
&lt;readmore&gt;
&lt;code&gt;
#!/usr/bin/perl -w
use lib ".";
use Test;

use strict;

$a = 0;

while ($a &lt; 5)
    print ++$a, "\n";
    for $b (1..10)
        print "$a $b\n";
    for $b (11, 12)
        print "$a $b\n";

print "done\n";
&lt;/code&gt;
As you can see, I added &lt;tt&gt;use Test;&lt;/tt&gt;, because my test module will be named &lt;tt&gt;Test.pm&lt;/tt&gt;. I like keeping things simple and obvious. &lt;tt&gt;use lib ".";&lt;/tt&gt; is there to make sure I'm not using the other module called [cpan://Test] :).
&lt;/readmore&gt;
&lt;/p&gt;
&lt;p&gt;
I have no idea how Python's indenting rules are, and don't really want to know either. So I decided to create some rules:
&lt;ul&gt;
&lt;li&gt; A literal tab character has a width of 8
&lt;li&gt; To create a block, increase indent
&lt;li&gt; To end a block, decrease indent, but no more than the indentation of the line before the block that you're ending
&lt;/ul&gt;
&lt;readmore&gt;
&lt;code&gt;
foo
    bar;
  baz
    quux
        xyzzy
            blah;
moo
&lt;/code&gt;
equals, more or less:
&lt;code&gt;
foo {
    bar;
}
baz;
{
    quux {
        xyzzy {
            blah;
        }
    }
}
moo
&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Source filtering is cool. Dangerous and scary, but extremely cool. And with [cpan://Filter::Simple], it's also very easy.
&lt;code&gt;
package Test;
use strict;
use Filter::Simple;

FILTER_ONLY code =&gt; sub {
    no warnings;
    my @lines = split /\n/, $_;
    my @indents;
    for (@lines) {
        my ($indent) = /^(\s*)/;
        $indent =~ s/\t/12345678/g;
        $indent = length $indent;
        if ($indent &gt; $indents[-1]) {
            s/^/{/;
            push @indents, $indent;
        } elsif ($indent &lt; $indents[-1]) {
            while ($indent &lt; $indents[-1]) {
                defined pop @indents or last;
                s/^/}/;
            }
        }
    }
    $_ = join "\n", @lines;
    $_ .= "}" x @indents;
};
1;
&lt;/code&gt;
As this is a quick hack, I added &lt;code&gt;no warnings;&lt;/code&gt; to get rid of warnings caused by the initial emptiness of &lt;code&gt;@indents&lt;/code&gt;. I also did not do much testing. To be honest: &lt;tt&gt;test.pl&lt;/tt&gt; was the only test I did. I hate forced indenting, so I'd rather not write more testing code for this :)
&lt;/p&gt;
&lt;p&gt;
Anyway, this works. Maybe Python coders like Perl better now. Perhaps not.
&lt;/readmore&gt;
&lt;/p&gt;
&lt;p&gt;
Perl can, without a lot of code, support forced indenting. I wonder if Python people can hack up something to support curly delimited blocks in Python, without mandatory indenting.
&lt;/p&gt;
&lt;p&gt;
Is Python flexible enough? (I'm asking this in the wrong place; I should be trolling a Python forum instead.)
&lt;/p&gt;

&lt;p&gt;
&lt;small&gt;Please do not use this module. Mandatory indenting is evil.&lt;/small&gt;
&lt;/p&gt;
&lt;p&gt;&lt;font color="#800000"&gt;
Juerd
# { site =&gt; '&lt;a href="http://juerd.nl/" target="_blank"&gt;&lt;font color="#800000"&gt;juerd.nl&lt;/font&gt;&lt;/a&gt;', plp_site =&gt; '&lt;a href="http://plp.juerd.nl/" target="_blank"&gt;&lt;font color="#800000"&gt;plp.juerd.nl&lt;/font&gt;&lt;/a&gt;', do_not_use =&gt; '&lt;a href="mailto:spamcollector_perlmonks@juerd.nl" target="_blank"&gt;&lt;font color="#800000"&gt;spamtrap&lt;/font&gt;&lt;/a&gt;' }
&lt;/font&gt;&lt;/p&gt;
P.S. / Update: I'm not actually being serious :)&lt;br&gt;&lt;br&gt;
Another update:&lt;br&gt;
&lt;pre&gt;
10:09 &amp;lt; scrottie&gt; hrm.  should write a source filter that reads white-space structured 
                  perl and adds the { and }'s
10:09 &amp;lt;@Juerd&gt; scrottie: Sorry.
10:09 &amp;lt;@Juerd&gt; scrottie: http://perlmonks.org/index.pl?node_id=266609
10:09 &amp;lt;@Juerd&gt; I win :)
10:09 &amp;lt; scrottie&gt; no kidding!?
10:09 &amp;lt;@Juerd&gt; This was 2 days ago, even :)
10:09 &amp;lt; scrottie&gt; you're a crazy fuck, you know that?
&lt;/pre&gt;</field>
</data>
</node>
