Text::Templet Use Scenario

If your web site is hosted on Apache server, you can configure it so that you can use Text::Templet and Perl with the ease of PHP. No more CGI/Perl scripts! The reason PHP is easy to use is that in the simplest case it is just an HTML page. You can create as many as you want, you don’t need to worry about setting permissions, and it’s very easy to debug because you get a meaningful response right in the browser instead of a 500 Server Error and digging error details from server logs.

Apache server has a mechanism that allows you to create custom content handlers – you can make Apache launch a specific program or script when a file with a particular extension is requested, and send its output to the browser. Best of all, this feature can be configured from the .htaccess file, and thus is available at many shared web hosting accounts.

To make this work, we need three things: a content handler script, a folder with template files containing your application, and an .htaccess file in the root of that folder.

Let’s start with the handler code:

use Text::Templet;

my $pagetext;
local(*PAGE, $/);
open (PAGE, $ENV{'PATH_TRANSLATED'})     || die "can't open file $_[0]: $!";
my @fstat = stat(PAGE);
read(PAGE,$pagetext,$fstat[7]); # $fstat[7] is the size of the file
close PAGE;
print "Content-type: text/html\r\n\r\n";


if ( $@ )
my $errortext = $@;
print "<body><div>Error:</div><div><pre>$errortext</pre></div><div></body>";

The handler is very simple – it loads the requested file passed to it by Apache in PATH_TRANSLATED environment variable, sends a standard HTTP header and passes the contents of the file to Text::Templet for processing. Any errors in the template will be reported through the $@ variable and displayed in the browser.

.htaccess file looks like this:

AddHandler pa-handler .pa
Action pa-handler /cgi-bin/pa.pl
DirectoryIndex index.pa

The following assumptions are made: the handler code above is saved in /cgi-bin/pa.pl, with executable permission set, and our template files have .pa extension. In addition, index.pa will be called when only directory is requested.

Finally, a simple template to get you started:

use vars qw($hello);
$hello = "Hello, World!";
Perl Application says: $hello

I’ve put all these pieces together to make it easy for you to try it out. Download pa.tar.gz or pa.zip, extract pa.pl and Text/Templet.pm from cgi-bin into cgi-bin folder on your web server, then create a new folder somewhere in your html document tree and extract .htaccess and hello.pa into it. Verify that pa.pl has execute permission set and open http://yourserver/folder/hello.pa . Click here to see this example code running on my web host.

You can use this example as a starting point and add features such as authentication and security. You can also put your Perl code in modules and reference them from your templates.

Performance of Perl Regular Expressions

Perl owes much of its power to regular expressions, making programming easier and more intuitive. But this power often comes at a cost – parsing and processing regular expressions is a non-trivial task that uses quite a few CPU cycles.

In some situations it is possible to significantly reduce the amount of time necessary for a particular processing routine by avoiding regular expressions altogether and using other techniques. Consider, for example, a task of extracting file name from a string containing a full path. Presented below are three functions that accomplish this using three different methods, along with their performance analysis.

Function filename1 splits the path into parts using path separator and returns the last part as the file name:

sub filename1
    my @tok = split /\//,$_[0];
    return $tok[-1];

The same result can be achieved using a slightly different approach – write a regexp that takes the part between the last path separator and the end of string:

sub filename2
   $_[0] =~ /\/([^\/]+)$/;   
   return $1;

Both functions are elegant and neat, but when it comes to performance, the following code is the best:

sub filename3
   return substr($_[0],rindex($_[0],'/')+1);

rindex() finds the index of the rightmost separator character in the string and then the file name is extracted using substr().

Here’s how long it takes all three functions to parse ‘/abc/def/geg-geg/page.pl’ 30000 times:

function1: 0.580 seconds
function2: 0.541 seconds
function3: 0.260 seconds

With a longer path ‘/abc/def/geg-geg/page.pl/abc/def/geg-geg/page.pl/ abc/def/geg-geg/page.pl/abc/def/geg-geg/page.pl’ the difference is more dramatic:

function1: 1.191 seconds
function2: 1.101 seconds
function3: 0.271 seconds

These are typical performance figures produced by the Perl profiler (Devel::DProf.) In this particular example, replacing a regular expression with search and substring extraction has reduced execution time by 50 to 75%.

Javascript Object Explorer

I’ve created a simple tool to aid in Javascript development to browse the properties of client-side Javascript objects. Javascript Object Explorer works with IE6/IE7 and FF2 on Windows, I haven’t tested it with other browsers yet. Its purpose is to show which properties are exposed to Javascript programs by different browsers. To check it out, click here. There is a similar tool on the Web also called Javascript Object Explorer, which can be pointed to an arbitrary page. I may implement this feature if there is significant interest. (Done!)

I Discovered Eclipse and CDT

I discovered Eclipse, a multi-platform, multi-language IDE. I got interested when I read a news article somewhere that Eclipse is not just for Java anymore, and I wanted to try it out since. Recently I had a couple of ideas to play with but I was not looking forward to doing it the hard way, with a text editor and command line tools. Since I decided to adopt GCC, I was interested to see if GCC could be integrated into some generic IDE, and Eclipse seemed like a good place to start looking, and I was blown away by it. I wish I have tried it sooner!

Here I want to share what I’ve found so far.
Continue reading I Discovered Eclipse and CDT