Random Notes on Intermediate Perl/Emacs Stuff

The learning curve is steep. It’s hard to know what to prioritize. Perl makes life easier, though, in that the bottom 30% of the language is so all around useful, you can get all kinds of things done even though you “speak Perl like a three year old.” For the rest of it, I just stop every few weeks and take an hour to focus on the two or three things that bug me the most. My theory has been, that as long as the combination of Unix-like shell, Emacs editor, and Perl scripting is applied to my daily work, there’ll always be enough payoff that it’s worth my while to learn the things I’ve been putting off– so that in 6 to 8 months I’ll actually start to gain some genuine skill.

Here’s a few things like that that I finally took the time to address:

(global-font-lock-mode 1)

Put this in your .emacs file to enjoy the wonders of syntax highlighting. Yea. (I wondered why the Windows version was in color where the Cygwin version wasn’t….)

There’s also two Perl modes, for some reason. I actually kind of liked the default one better than the M-x cperl-mode that you’re supposed to use instead. In color, your hashes look atrocious… and your useless spaces show of as abrasive underscore lines…. I use those lines to mark my place in my project– to sort of delineate where I’m working. Cperl-mode seems a little more sluggish to me when it has to place your braces where they belong, but I like the way it spaces things better. (And people talk about how hard it is to parse Perl… it wasn’t long before I broke the syntax highlighting with a line that had a mess of single and double quotes on it. Maybe switching color mode on was not a good idea.)

Perl has anonymous functions and also functions that operate in list context. As much as Larry hates parentheses, it’s clear that he doesn’t hate Lisp concepts….

If you’ve got an array of strings, you can grep them with an anonymous function. Map can be used in a similar way:

my @array = qw/ apple bus cat dog elephant/;
my @things = grep {length($_) > 3} @array;
print "*$_*\n" for @things;
my @stuff = map {"--$_--"} @things;
print "test: $_\n" for @stuff;

# Altogether now:
print map {"!!!$_!!!\n"} grep {length($_) == 3} @array;

Now here’s the cool thing. I’m thinking to myself… wouldn’t it be great if you could refer to files streams in list context? And sure enough…

print map {“!!!$_!!!\n”} grep {length($_) == 3} <>;

This works! All of that accidental complexity in my Perl scripts due to excessive looping and if-then-else blocks… this one idea puts a huge dent in it.

I have to admit, this gave me flashbacks to my college Calculus class. We’d been working through a huge number of problem sets for a few weeks… and the professor comes in and teaches us a trick that showed us we were really doing things the hard way. The “regular” kids were disgusted. Why did he waste all our time? My theory was, that for most of us, we would not have appreciated the trick (and maybe not even understood it) if we hadn’t done the work first. Back at the code bench, this translates to… write bad Perl scripts to do practical things at work. Then clean them up with map and grep. Now you *really* know what they were trying to tell you back in chapter 3 of SICP! You know it down in your fingernails….

Okay, one last note. A few weeks ago, we saw that to really get functions to work with accepting arrays as arguments and returning groups of them for their return values, you had make the mental and semantic leap to begin thinking in terms of references. This seems to be a little tricky, because it doesn’t appear to be a “reference” like what I’ve seen in other languages– maybe it is, but if I “my” the sucker in a subroutine, it looks like that’s copying it, at the very least. Anyways, I’ll gradually assimilate that in time. We don’t really care what a reference really is yet– we just want stuff to work! Especially with hashes!!

my ($foo, $bar) = test2();
my $value = ${$bar}{2};
print "The value of foo is $foo and the value is $value\n";
print "We could have just said, '${$bar}{2}', too.\n";

sub test2 {
  my $foo = "hello";
  my %bar;
  $bar{2} = "world!";
  return ($foo, \%bar);
}

So, to cast the reference (stored in a scalar) into a hash so that we can ‘talk’ to it, we have to ‘fancy’ it in two places. I was thinking that the curly braces around the key would tip Perl off as to what we were trying to do…. And when that didn’t work, I was thinking that some sort of casting with a % sign somewhere would be the ticket. Thanks to Intermediate Perl, though, we know what we need to keep rolling….

Advertisements

9 Responses to “Random Notes on Intermediate Perl/Emacs Stuff”

  1. Dan G Says:

    Since you seem to be interested in Perl. I found a pretty interesting unexpected behavior with scoping in Perl.

    Maybe it’ll give you some ideas: http://www.dangoldin.com/blog/2008/05/30/interesting-perl-behavior/

  2. lispy Says:

    Ah…

    “The behaviour of a my statement modified with a statement modifier conditional or loop construct (e.g. my $x if … ) is undefined.”

    That’s scary. Hadn’t thought to use “my … if” anyways. I usually just suck it up and break that thought into two lines, that way I have a mostly explicit undef situation…. I think….

  3. Pete Wilson Says:

    Just a syntactic TMTOWDI, but …

    print “We could also have said, ‘$bar->{2}’, too.\n”;

    I like to use the arrow notation when de-referencing array or hash refs.

  4. lispy Says:

    No, that’s fundamentally better. Perl Best Practices covers a similar technique for use with arrays, but I didn’t see the equivalent for hash tables like you used. Very nice. Thanks.

  5. Seth Says:

    I like the perlnow elisp package for developing perl in emacs. Adds a lot of helper functions (like syntax check).

    http://obsidianrook.com/perlnow/

  6. lispy Says:

    I just found the elisp code in Perl Best Practices and I’m eager for more…. Thanks….

  7. Johan L Says:

    It may be overkill if you’re just scripting a bit with Perl, but otherwise Devel::PerlySense may be useful.

    http://search.cpan.org/~johanl/Devel-PerlySense-0.0158/lib/Devel/PerlySense.pm

    Install like so:
    cpan Devel::PerlySense

  8. dangoldin Says:

    Yea. I’ve started breaking down the my … if into two separate lines. Makes code cleaner and avoids that issue.

  9. Joseph Brenner Says:

    Does cperl-mode still do that annoying display of trailing space as underscores?
    Hm, yes I guess it does, by default. I haven’t seen it in a long time, because
    I’ve got this in my .emacs:

    ;; trailing spaces should *not* be displayed as underscores!
    (setq cperl-invalid-face nil)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: