More Boom In The Room

This is my personal weblog, usually with stuff about music and other geeky things.

Monday, July 14, 2008

HOWTO install Oracle Instant Client with MacPorts

In the process of getting a working PHP + Oracle installation going on my Mac, I found out that the MacPorts project has most of the bits already set up for me. Trouble is, the usual way it handles downloads doesn't play nice with Oracle's web site, which expects you to accept a license agreement with your web browser before offering their Instant Client for download.

I had incorrectly reported this as a bug in MacPorts, but Instant Client port maintainer Ryan Schmidt set me right and told me how to install it after downloading the required files in my browser. Not the best solution, but it worked. Thanks Ryan!

Thursday, July 10, 2008

Batch-checking that a set of Perl modules compile

cd module-dir; find . -name '*.pm' -exec perl -c {} \; 2>&1 | fgrep -v 'syntax OK'

Monday, June 16, 2008

HOWTO fix Perl IO::Uncompress::RawInflate errors in CPAN shell

I've run into this problem repeatedly on my work PC. Unfortunately the solutions I've seen seem to be specific to Linux distributions, and I'm using Cygwin on Windows XP. So here's my (hopefully cross-platform) solution: manually download the IO::Compress::Zlib tarball from CPAN, then build and install it manually as per the README file. The CPAN shell should now be able to unpack things again.

Monday, June 02, 2008

Stupid school threads

The typical directions for online threaded discussions -- "make one initial post and two replies to others' initial posts" -- actually hinder critical engagement. The common practice of requiring all students to make initial posts invites redundancy and banality; it also starts too many parallel conversations, dispersing the discussion and multiplying the information on-screen needlessly.


This perfectly crystallizes my repeated frustration with the threaded discussions that are part of my online and hybrid classes at DeVry. There's so much crap, and unlike many of my classmates I'm uncomfortable with replying with some padded equivalent to "me too".

Friday, May 30, 2008

$5 music gift card for The Phoenix Trap

So The Phoenix Trap's music is now on AmieStreet.com, and to kick things off they are giving our fans (both of you ;-) $5 to download our music.

All you have to do is click on this link to get $5 to download our music or songs from tens of thousands of other great independent artists.

Here's the fun part — as of this writing, our songs are free to download there, but will go up in price (up to 98 cents a song) based on how much they're bought. So if you go now you can probably get all of them for nothing (or next to nothing) and use the $5 on other stuff.

Why am I still flogging this years after the band broke up? Well, our digital distributor CD Baby still has the CD in stock, and this is what they do. Seems like a good deal even if we've all since moved on.

Tuesday, April 22, 2008

Now using Disqus for comments

Not that I get many on here these days, but there you go. Doing it mainly for the Plaxo Pulse integration. This post serves as a test for the new comments.

Friday, April 11, 2008

Under-appreciated Perl functions: map, grep and exists

I've recently taken more direct ownership of a big Perl application at work, and in the process of adding a new feature noticed a lot of this type of looping code:

# loop 1
my %foo_types = ();
foreach my $entry_data_ref (@entry_data) {
$foo_types{ $entry_data_ref->[19] } = $entry_data_ref->[20];
}
my $foo_types_regex = '(' . join('|', keys %foo_types) . ')';

# loop 2
foreach my $data_ref (@data) {
my $id = $data_ref->[0];
push(@ids_to_disable, $id) if $type_cd =~ m/^$foo_types_regex$/;
my $type_cd = $data_ref->[21];
}

I managed to simplify it down to this:
# loop 1
my %foo_types = map { $_->[19] => $_->[20] } @entry_data;

# loop 2
my @ids_to_disable = map $_->[0], grep exists $foo_types{ $_->[21] }, @data;

See the difference? Both loops are concerned with generating one list from another -- the first transforms a list into a hash, the second uses the keys of that hash to determine the contents of another list. This is what map (and its cousin, grep) are built for. The foreach loop in the original hides the intent of the code, and it's likely slower as well since map knows how many elements it needs to process and can preallocate space on the list it returns.

The original loop 1 also populated a string with hash keys to use as a regular expression later in order to find out what entries to get out of @data in loop 2. But again, we have a much more appropriate function for this: exists. Checking for a hash hit is near-instantaneous compared to working through a long regular expression, and again it makes the code smaller and easier to understand and debug.

map and grep come from the more functional-programming side of Perl, and they seem to be very underused and under-appreciated by people used to more traditional procedural languages like C and Java. It's unfortunate, because it leads to much more bloated code that takes longer to debug, and doesn't use the language's full capabilities.

About Me

My Photo
Mark Gardner
Warrington, Pennsylvania, United States
I get paid to hack code. Sometimes it even runs. I also used to play bass in a band.
View my complete profile

Previously...