Delving the depths of computing,
hoping not to get eaten by a wumpus

By Timm Murray

Dynamic Perl Code Loading

2013-08-30


There’s a trick done by mod_perl for running old-style CGI scripts. These have to be loaded on-demand, but how do we load code into the parser at runtime?

Well, eval(STRING), of course. Really, there’s no magic to it beyond that. This often maligned feature is at the heart of not just mod_perl, but also pretty much any templating system that embeds Perl code inside. Isn’t that dangerous, you ask? Not really; you presumably trust the code coming from template files on your own server. It’s no more dangerous than downloading a random CPAN module and loading it up.

Generally, they don’t eval the straight code. They wrap it up inside a package and a subroutine, then call the sub. Something like:

my $loaded_code = ...;
my $full_code = <
# Sometime later
Known::Package::Namespace->run;

Things can get more sophisticated than this. Perhaps you expect to load up multiple code files, so you generate a predictable package name for each one (maybe based on the file name). Maybe the run() sub takes an argument, like $request for the Apache request object, which will then be available to the loaded code.

One problem with the above as written is that it screws up error messages for the filename and line number reporting. If you use the debugger, it’ll screw up it outputting the code you’re stepping through. This is where a trick with Perl comments comes in handy, where the line number and file in error messages can be set in a comment. It’ll work something like:

sub run
{
    # line 1 $filename
    $loaded_code
}

And all is well in the world. In the case of templating systems, you might want to keep track of the line number you’re getting the code from, and fill that into the line directive, too.



Copyright © 2024 Timm Murray
CC BY-NC

Opinions expressed are solely my own and do not express the views or opinions of my employer.