Best. Perl. Utility. Evah.
Dec. 22nd, 2004 03:03 pmSomething 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 };’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:
if ($x == $b or $foo == $bar) {
&thing;
}
-e syntax OK$ perl -MO=Deparse -e ‘if (($x == $b)) { };’
if ($x == $b) {
();
}
-e syntax OK
$ perl -MO=Deparse -e ‘print “nothing”;’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:
print ‘nothing’;
-e syntax OK
$ perl -MO=Deparse -e ‘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:
print ‘no->thing’;
@columns = split(/ */);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(’ *’);
...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);
@columns = split(//);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:
@columns = split(””);
@columns = split(’’);
...gets turned into...
@columns = split(//, $_, 0);
@columns = split(//, $_, 0);
@columns = split(//, $_, 0);
$ perl -e ‘print join(”:”, split(//, “test”) ), “\n”;’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?
t:e:s:t
$ perl -MO=Deparse -e ‘print join(”:”, split(//, “test”) ), “\n”;’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:
print join(’:’, split(//, ‘test’, 0)), “\n”;
-e syntax OK
@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.
no subject
Date: 2004-12-22 01:59 pm (UTC)no subject
Date: 2004-12-22 02:47 pm (UTC)no subject
Date: 2004-12-28 08:49 am (UTC)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.