I gave a talk about functional programming with Perl at Salt Lake Perl Mongers.
I don’t mess with procmail
much anymore, but maybe these will be useful to someone.
Split a mailbox into separate files for each message:
$ formail -s sh -c 'cat - > foo.$FILENO' < klez.file
Resend a mailbox (foo) through a set of filters (rc.test
):
$ formail -s procmail ./rc.test < foo
Move the last 10 messages from folder foo
and put them in folder bar
:
$ MSGS=`egrep '^From ' foo | wc -l`
$ formail +`expr $MSGS - 10` -s < foo > bar
Check which recipes triggered most often (based on a verbose log format):
I gave a talk about asynchronous programming patterns in Perl at Salt Lake Perl Mongers. This presentation ultimately landed me a new job—thank you to SLC.pm!
Here are some Perl goodies I forget to write down once I’ve remembered them long enough to solve my problem.
Line range
If you want to print all the lines in a file after a certain line number:
perl -ne 'print if (2655641 .. -1)' some.log
This will print from line 2655641 to the last line (-1
).
Omiting chunks
Sometimes you have chunks of lines, or multi-line records, that you want to skip.
DBD::mysql
knows that certain MySQL column types are integers with this call:
$sth->execute;
$nums = $sth->{'mysql_is_num'} || [];
You can iterate over $nums
and see which columns are numeric-type columns. However, when you pull the data out, it’s converted to a string. So, what used to be as simple as this:
my $accounts = $sth->fetchall_arrayref({});
now requires this kind of trickery:
my @accounts = ();
my $is_num = $sth->{'mysql_is_num'} || [];
while (my $row = $sth->fetchrow_arrayref) {
push @accounts, {
map {
$Acct_Fields[$_] => ## key
($is_num->[$_] ## check to see if it's int
? 0 + $row->[$_] ## coerce to integer/numeric
: $row->[$_]) ## leave it alone
} (0 .. $#Acct_Fields) ## number of keys
};
}
This seems to work as a primary test to see if a scalar ($val
) is an number-ish thing:
Here’s a nice trick from perlfunc
’s map
entry:
To force an anon hash constructor use "+{":
@hashes = map +{ lc($_) => 1 }, @array # EXPR, so needs
# comma at end
to get a list of anonymous hashes each with only one entry apiece.
Say you have a hash:
my %hash = (foo => 'fooey',
bar => 'barey',
baz => 'bazey',
blech => 'blechey');
and you want to rename some of the hash keys, create another hash that holds the new names of the keys:
## old-name => new-name
my %new = (foo => 'foooo',
bar => 'baaar');
Then this is a fast way to rename the keys. Measured on 2.4Ghz i5 MacBook Pro.
I don’t use emacs’ artist mode often enough to remember all of the keystrokes and finding the reference sometimes is effort than it’s worth.
To enable:
M-x artist-mode
to disable:
C-cC-c
Here is the list of commands from the artist.el
file:
C-cC-aC-r artist-toggle-rubber-banding
C-cC-al artist-select-op-line
C-cC-aL artist-select-op-straight-line
C-cC-ar artist-select-op-rectangle
C-cC-aR artist-select-op-square
C-cC-as artist-select-op-square
C-cC-ap artist-select-op-poly-line
C-cC-aP artist-select-op-straight-poly-line
C-cC-ae artist-select-op-ellipse
C-cC-ac artist-select-op-circle
C-cC-at artist-select-op-text-see-thru
C-cC-aT artist-select-op-text-overwrite
C-cC-aS artist-select-op-spray-can
C-cC-az artist-select-op-spray-set-size
C-cC-aC-d artist-select-op-erase-char
C-cC-aE artist-select-op-erase-rectangle
C-cC-av artist-select-op-vaporize-line
C-cC-aV artist-select-op-vaporize-lines
C-cC-aC-k artist-select-op-cut-rectangle
C-cC-aM-w artist-select-op-copy-rectangle
C-cC-aC-y artist-select-op-paste
C-cC-af artist-select-op-flood-fill
To selectively profile during only a portion of the code, invoke like this:
$ NYTPROF=start=no perl -d:NYTProf t/load.t -v
Then inside t/load.t
add the following directives which tell Devel::NYTProf
to start and stop profiling:
DB::enable_profile();
... ## profile this section
DB::finish_profile();
Add use Devel::NYTProf;
in either the test file or in the module.