Showing posts with label perl. Show all posts
Showing posts with label perl. Show all posts

Wednesday, July 14, 2010

Can't Locate Object Method via Package

I recently got a confusing Perl error message for a line of code that I thought was a simple assignment to a hash member:

Can't locate object method "patterns" via package "objdir(/[^ ]*)?" (perhaps you forgot to load "objdir(/[^ ]*)?"?) at ./filter.pl line 24.

A Google search turned up many forum entries asking about the message, but they all had to do with open-source projects where there was indeed a package method call that had gone wrong.

After I rubbed my eyes long enough, it was obvious what I had done: left the '$' off the front of the hash reference. I had typed:

    patterns{"objdir(/[^ ]*)?"} = "dirs/objs"; # WRONG!

instead of:

    $patterns{"objdir(/[^ ]*)?"} = "dirs/objs";

I even had use strict; use warnings; on, but only got the error message. Anyway, since Google didn't help me out, let's see if this page with the error text in the title floats to the top and helps someone else out someday.

Wednesday, July 15, 2009

Perl Cwd Performance

The Camel book says -- in the Efficiency section of Chapter 24 -- to use the Cwd module instead of calling pwd repeatedly.

Boy, it's not kidding. I wrote a test script that does almost nothing but change directories and print the current directory, repeating that about 7500 times. Using `pwd` to get the directory took an average wall-clock time of 11.7 seconds. If instead you import Cwd's version of chdir(), the script can use $ENV{PWD}, which took an average wall-clock time of 0.3 seconds.

Oddly, using Cwd::cwd() took an average of 15.4 seconds. This wasn't a very scientific test, but those numbers bore up under repeated tries (doing several runs in a row, throwing out the time for the first run). I used wall-clock time, because the sys/user time reported by Unix time was quite a bit lower, even though it was an unloaded system. Maybe because the directories were NFS mounts.

So here's a good strategy for using Cwd:

use Cwd qw(chdir);
sub cwd {
return $ENV{PWD};
}


Note: the Cwd documentation points out that $ENV{PWD} is only kept up to date if every module used in the script uses Cwd::chdir to change directories.