yesthattom: (2000formal)
[personal profile] yesthattom
Something I learned at M.J. Dominus’ LISA2004 tutorial was about cleaning up code with too many parentheses. Beginning programmers like to put in excess parentheses. This is because they are afraid of precedence effects. M.J. Dominus says, “Don’t be superstitious”. Perl has a function that will re-write your code without the superstitions. Check it out:

$ perl -MO=Deparse -e ‘if (($x == $b) || ($foo == $bar )) { &thing };’
if ($x == $b or $foo == $bar) {
    &thing;
}
-e syntax OK

$ perl -MO=Deparse -e ‘if (($x == $b)) { };’
if ($x == $b) {
    ();
}
-e syntax OK

And you know how perl is smart enough to turn a double-quoted string into a single-quoted string when there is nothing to interpolate? We can see that right here:
$ perl -MO=Deparse -e ‘print “nothing”;’
print ‘nothing’;
-e syntax OK
Since there were no special characters, it was optimized to be a ‘single quoted string’. Which reminds me. I once put backslashes in front of characters that I think need to be quoted but wasn’t sure. Now I can be:
$ perl -MO=Deparse -e ‘print “no\-\>thing”;’
print ‘no->thing’;
Ah! I didn’t need those backslashes after all! But wait, it gets better. It rewrites things to clarify some of the more confusing things about perl. For example, the “split” operator takes a regex... even if you give it a string. Many people (including myself) forget this and can’t figure out why splitting on ’ *’ doesn’t work as expected. That’s because even though you included it in quotes, it gets used as a regular expression:
@columns = split(/ */);
@columns = split(’ *’);

...gets turned into...
@columns = split(/ */, $_, 0);
@columns = split(/ */, $_, 0);

...for the same reason that...

@columns = split(/tom/);
@columns = split(”tom”);
@columns = split(’tom’);

...gets turned into...
@columns = split(/tom/, $_, 0);
@columns = split(/tom/, $_, 0);
@columns = split(/tom/, $_, 0);

Fun, right? And have you ever wondered if there is a difference between the three kinds of nulls (”” and ‘’ and //) in perl? Well there isn’t anything special about them. They’re all turned into the same regular expression. We can prove it because
@columns = split(//);
@columns = split(””);
@columns = split(’’);
...gets turned into...
@columns = split(//, $_, 0);
@columns = split(//, $_, 0);
@columns = split(//, $_, 0);
Which is not “special”, it’s just strange. It matches the null string, which is sort of special, since it splits the string into each character:
$ perl -e ‘print join(”:”, split(//, “test”) ), “\n”;’
t:e:s:t
Of course, we can pass it through Deparse to see that we could have used single quotes two places on that line. Not that we mind perl optimizing where we forget. In this case, since we were running the command on the command line surrounded by single quotes, its easier to use double-quotes so we don’t have to use backslashes. Got that?
$ perl -MO=Deparse -e ‘print join(”:”, split(//, “test”) ), “\n”;’
print join(’:’, split(//, ‘test’, 0)), “\n”;
-e syntax OK
Ok, there is one special case in “split” and that is to get the “awk behavior” you either call it with no arguments or with a single space in quotes. The perldoc page doesn’t make it clear that either kind of quotes are the same. Just don’t put a single space between two slashes because that is not the special case:
@columns = split(” “);
@columns = split(’ ‘);
@columns = split(/ /);

...becomes...
@columns = split(” “, $_, 0);
@columns = split(” “, $_, 0);
@columns = split(/ /, $_, 0);

I wish I had known about this years ago.

Date: 2004-12-22 01:59 pm (UTC)
From: [identity profile] awfief.livejournal.com
hee hee. I shall use that before attempting to figure out ANY perl code. it's neat that it explicitly puts in $_, too. I'm always looking at something going, "so what the heck are they modifying, anyway?" Then again, I comment my code up the bejeezus and don't deal with much of other people's code to begin with.

Date: 2004-12-22 02:47 pm (UTC)
From: [identity profile] rampling.livejournal.com
I'm just starting to learn Perl now at work, and I'll make a note of this. Cool!

Date: 2004-12-28 08:49 am (UTC)
From: [identity profile] stitchinthyme.livejournal.com
I'm finally catching up, hence the late reply. I'll definitely have to remember this. I'm not a beginner as far as Perl is concerned, but I do probably sometimes use parentheses where they may not be necessary -- mostly because I don't always remember the precedence rules and I'm too lazy to look them up. And I didn't know that even quoted strings get treated as regexes in split(), though it makes sense; once I had to debug someone's nonworking code and it turned out that they had something like:

split("|", $blah);

This didn't work because it apparently tried to treat the pipe like a regex "or" rather than the literal character, so it had to be changed to /\|/ in order to work.

December 2015

S M T W T F S
  12345
6789 101112
13141516171819
202122 23242526
2728293031  

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Feb. 4th, 2026 07:20 am
Powered by Dreamwidth Studios