Reviews by Mark Stosberg


REST-Consumer (0.07) **

The projects looks like a good first effort, so far lacks some particularly useful features and the documentation is incomplete. Only JSON is supported currently, and there appears to be no easy way to set custom headers. I instead recommend looking at Role::REST::Client, which supports more data types, custom headers, and makes it easy to create on object that bundles in your project-specific requirements.

(To the author: I attempted provide direct feedback, but your address bounced.)

Test-WWW-Mechanize-CGIApp (0.05) **

This hasn't been updated to keep parity with similar modules. These days there is a better alternative. You can instead use CGI::Application 4.50+, and Test::WWW::Mechanize::PSGI.

LWP-UserAgent-Determined (1.06) *****

Useful, versatile, and well-documented. Recommended.

HTTP-Async (0.09) ****

Small, fast, and easy to use. With HTTP::Async, I'm able to download about 50 (small) images per second to a ramdisk.

The "info()" method for human-friendly status reports is a nice touch.

I find just one feature lacking, which is the ability to not collect the responses and completely ignore them. In my use-case, both my client and the server update the same database, providing another communication channel. This limitation can still be easily worked around by polling "wait_for_next_response()" and throwing away the return value.

Overall, recommended as a asynchronous HTTP library.

HTML-ReportWriter (1.5.1) ***

A long time ago I started using HTML::ReportWriter::PagingAndSorting to help generate paging and sorting links on web reports. I don't use the main "ReportWriter" module. It works OK, has some downsides to consider. This module has no automated tests. Since the time it was released, changed it's behavior of the url() method that this module uses, and this distribution had no regression tests to make sure that modules it depends on continue to behave the same. Also, PostgreSQL can now select a page of data along with the total results in one query instead of two for better performance, but this solution still uses the two query technique in all cases. Finally, the author has yet to respond submitted patches, the oldest submitted 5 years ago. In summary: it works, but I'd shop around further before using it in a new project.

CGI-Application-Plugin-RateLimit (1.0) ****

This CGI::Application plugin allows to add custom throttling rules to you application. Having implemented it now, it seems easy to use, flexible, and well documented.

My one complaint is that it lacks a "singleton mode" like the ::TT plugin for CGI::Application has. Currently, there are several methods that need to be called on each request to configure the plugin. A singleton feature would allow details to be configured once at server start time, requiring less time during each request. ( That said, I have no indication that current design presents a performance bottleneck. )

Object-New (0.02) *

While I welcome contributions from new contributors, I agree with the recommendation to use the competing Object::Tiny module over this one. This one doesn't handle creating accessors and doesn't contain any automated tests of the little functionality it does include.

Spreadsheet-WriteExcel-Styler (1.00) *****

This module solves a small but important problem that I have experienced myself in a clean way. It is well-documented and includes a reasonable amount of automated test.

If you need to generate a dynamic Excel document of any complexity, I recommend trying this module.

Encode-Base58 (0.01) *****

I'm pleased to have this simple solution in Perl which would be useful for building a URL shortening service, or working with a service with uses Base58, such as

JE (0.038) ****

This is a serious effort to write a JavaScript Engine in Perl, and I'm glad that such a project exists. However, it failed two of my initial evaluations, including a basic loading of jQuery 1.3.2. I filed bug reports about both cases. It is also a known issue that is slow, with the trade-off that it has the hack-ability and portability of being in pure Perl.

Text-CSV_Multiline (0.01) *

Nothing to see here yet. The docs are just stubs, and Text::CSV_XS supports embedded newlines already. It's not clear what this potentially offers that's new in the CSV space.

HTML-Template-Dumper (0.1) *****

I don't know why it took my 5 years to try this module. Now that CGI::Application has the html_tmpl_class() method, this is a really practical testing tool. It returns a hashref of exactly the tokens that would be sent to a template file, including taking into account which tokens actually exist in the template file. This way, I can precisely unit test what would be sent to template, but without dealing with the full HTML, without modifying my code. A valuable testing tool!

HTML-Detoxifier (0.02) **

This module seems nicely constructed and documented, but I wouldn't use it for XSS protection. Choosing the 'dynamic' option would lead you to believe that all JavaScript would be covered, but I don't believe it covers in-line JavaScript, like <img src="javascript:foo()">.

Data-FormValidator-Filters-Image (0.40) ****

Downsizing images seems like a must-have tool for web developers these days. This module integrates cleanly with Data::FormValidator to provide that, and is well documented and well tested.

The only downside is that the solution is somewhat specific to

HTTP-Router (0.01) **

I was attracted to this distribution because of the novel interface. ( I rated the interface 4 out of 5 ).

I was willing to forgive the mostly missing documentation because it's the initial 0.01 release.

In cases like this, it's often possible to read the source and start to write some documentation myself. It seems to me it's put together in an overly complicated way. Take these two key lines in the 'define()' routine you see in the SYNOPSIS:

local $_ = HTTP::Router::Mapper->new(routeset => $self->routeset);

So define() takes a code block. In define() we build a new Mapper object, passing to it a new a RouteSet object which is initialized via routeset, _build_routeset and Mouse, and this result is stored in a local version of $_, which is then passed as an argument to the coderef that was provided to define().

I find that flow confusing.

When the documentation for this distribution improves, I'll be interested to take a second look at it more from a user's perspective, without peeking behind the curtain.

Apache-Test (1.30) **

I found the documentation of this module and the diagnostics less than helpful. An apparent bug triggered by CGI::Application::Dispatch has been a significant time sink for me ( ).

My experience has been that this module takes a fair of wrestling with.

Catalyst-Plugin-Compress-Zlib (0.03) ***

0.03 is a reasonable start, although it currently lacks any real tests. There is currently no way to customize the MIME types that are compressed, and there are no checks for minimum and maximum file size like mod_gzip has.

Catalyst-Plugin-Redirect (0.02) ****

The two previous reviews rated this down because Catalyst has a built-in redirect() method, which is true. This plugin has an additional feature which could make it worthwhile. It allows you to create provide a "relative" URL to redirect to, and it takes care of making it absolute for you. I think that's reasonable feature to have in a redirect system, and sufficiently different than the built-in redirect() function to be worthwhile.

HTTP-Engine (0.0.17) ***

This is a potentially useful solution for abstracting details of various web servers. The overall quality of the code and tests look reasonable from what I've seen. However, when I tried to download this module along with its dependencies, the result was over 200 Perl modules. For me, this is too much resource penalty for the functionality it provides. By contrast, Mojo serves a similar function and no dependencies beyond core Perl modules.

XML-FeedPP (0.36) *****

This pure-perl module wrangles RSS and Atom feeds with very few dependencies. This makes it ideal for distributing with other projects that may be deployed on multiple platforms.

If you need more speed or features, you may try a heavier weight solution, but I recommend starting here.

App-Todo (0.96) ***

As a fan of and Hiveminder, I'm glad this exists, is open source and is on CPAN. I'd still like to see a number of technical improvements to the distribution: 1. It has no automated tests. 2. All the code is in a script, not a module where it would be more re-usable. 3. There is essentially another project embedded in here, something like a "Net::Hiveminder::Lite". The calls to the Hiveminder API use here require few dependencies, and it would be great to make them more accessible.

File-Finder (0.53) ****

This is a superior interface to File::Find because it allows a more natural expression of what you want to do. I have used it and recommend it. It is not perfect because of the underlying architecture of File::Find, which does a 'stat' and runs a subroutine for every file and every directory involved. For large numbers of files or when performance matters, you can sometimes do much better by using 'glob' or 'readdir' to read the list of files. Perhaps if the "SPEED" section of the documentation was further updated to recommend when *not* to use, I would give this the full five stars. For any non-performance-critical task, I recommend it!

CGI-Application-Plugin-Config-Any (0.12) ****

A useful connector between Config::Any and CGI::Application. This plugin follows the standard for CGI::Application config files, so key calls to the config() method should be portable between different Config plugins.

Nagios-NSCA (0.1) **

I'm glad this was published, as it may be helpful to someone else working on a Nagios interface, but without any documentation or tests, it's not particularly usable yet.

Shipwright (2.0.0) **

The documentation is sparse and feels incomplete. For example, from the CPAN listing you can't even see that it ships with a "shipwright" binary, because there is no POD in it. The source code points you to Shipwright::Script, which has no real documentation either. From there, you might try "Shipwright::Script::Help", but the only documentation for that is: "shipwright help COMMAND show help".

It appears that it would support additional backends besides SVN and SVK, but Shipwright::Backend provides no documentation of the API for adding a new backend.

I think Perl really needs this kind of packaging and deployment solution, and I'm glad some people are working on it and releasing it as open source. This one just doesn't feel ready yet.

File-MMagic (1.27) ***

This is a handy module for determining the the file type of a file by examining its contents. However, it some serious bugs (currently 19 are open), and hasn't been updated in two years. I personally ran into problems with bad results under mod_perl.

I would strongly suggest looking for alternatives before using this module. If you just need to check common web image formats, File::Type::WebImages is a simple module for that purpose. It was written precisely because File::MMagic had problems in mod_perl.

CGI-Application-Plugin-FillInForm (1.14)

I co-authored this one, so I'm avoiding a formal rating.

When it was written in 2005, it provided a much nicer interface to HTML::FillInForm. However, those warts were all addressed in the HTML::FillInForm 2.00 release. The remaining value this adds to CGI::Application is defaulting to $self->query for the data source, and automatically ignoring "rm" as a form field. If those features aren't important to you, it would be simpler to use HTML::FillInForm 2.x directly.

IO-CSVHeaderFile (0.04) **

This module is decent, and I have used it in production myself. However, it seems the primary benefit of it is to add the feature to get rows as hashrefs to Text::CSV_XS, and that feature has been added to Text::CSV_XS as of the 0.40 release today. So at this point I would advocate just using Text::CSV_XS directly instead of this module.


LoadHtml (7.04) *

This is yet-another templating system, without any real tests, no POD documentation, and no mention of already existing templating systems to mention which this wheel re-invention would be any better than all the pre-existing templating systems.

HTML-FillInForm-Lite (0.01) ****

I"m alreaady been a long-time user and fan of HTML::FillInForm, so it's easy to recommend a version which drops the baggage of the older syntax, and is reportedly markedly faster. While it looks like it has a number of automated tests, it would be more confidence inspiring if the test suite from HTML::FillInForm was ported over to run for this as well, removing or translating any tests for it that used the older syntax.

Test-Aggregate (0.05)

This module to help speed up test suites is a welcome addition to the Perl quality assurance toolkit.

The documentation is clear and easy to follow. I like that you can switch tests over to this system incrementally, easing migration.

relative (0.03) ****

A neat idea to clean up repeating the same long name space frequently.

My only gripe is that it provides multiple similar syntaxes for doing the same thing, when I think one option would be sufficient, and make for simpler, clearer documentation.

self (0.13) ****

I'm going to consider using this because I'm tired of writing "my $self = shift" myself.

The code itself looked fairly clean and simple. No filters or deep magic.

In the most recent releases, 'self' is customizable, and it now works inside of 'eval'.

Spread-Message (0.21) **

While there may be some useful code in here, this distribution has very few tests and includes the red flag of a module named simply "Utils".

I wouldn't consider deploying this without thorough review and testing.

Data-Dump (1.08) *****

A worth successor to Data::Dumper.

Where "warn Dumper(\@a)" would produce a list like this:

$VAR1 = 1;

$VAR2 = [




$VAR3 = {

'4' => 5


With this module, you could write just "pp(\@)" and get a much
tidier result:

(1, [2, 3], { 4 => 5 })

And while Data::Dumper::Names is nice, it requires Perl 5.8.2. This module requires just 5.6, making it likely it work on nearly all Perl installations you encounter.

(To respond to David Garamond's rating: the "dump" and "pp" commands are the same. Also, I've submitted a patch to improve the docs).

CGI-Application-Tutorial-Namegame (0.01) ****

It's helpful to have this example code which shows how a view CGI::Application plugins can fit together. It could be improved with a little more documentation to walk through the code, although it is already rather straightforward.

HTML-Template-Default (1.03) **

It's an interesting and useful idea, but I question the implementation. This fixes the args passed into new() in away that isn't changeable, surely dis-allowing some preference options some people will want.

I would prefer to see this implemented as a sub-class or plugin.
I'm sure a new() trigger in HTML::Template::Pluggable could be added to support this.

I took off another star for the lack of a "Changes" file.

pmv (0.01) *****

Nice. It's like a polished version of the old "Larry's File name fixer" script:


HTML-Copy (1.22) *****

With an easy to use binary included, htmlcopy removes one more reason to use Dreamweaver. Now HTML files can moved around easily on the command line, keeping relative references within the HTML intact.

Module-CoreList (2.12) *****

Module authors are interested to know when (or if) a module was in the core to decide what dependencies to use, and which ones to declare. You can't get any easier than "corelist Module::Foo".

It worked great for me.

String-Truncate (0.102) ***

In the past I had written my own simple "elide" functions for different projects, but no more! This module looks to have to clear docs, and sufficient tests.

However, I have to tone down my enthusiasm for it became of the dependency chain. It depends on Sub::Exporter, which depends on Data::OptList, which had a "pod.t" that failed when I tried to install it:

"Insecure dependency in chdir while running with -T switch at /usr/local/lib/perl5/5.8.0/File/ line 807."

This might be a side-effect of trying to install the modules as a non-root user.

For similar, simpler module with no dependencies, see Text::Truncate instead.

pip (0.08a) ****

The concept is a step forward in making Perl projects easier to deploy. There remains a bootstrapping problem: You can't give an end-user a 'pip' file to install, because they won't have 'pip' to install it with.

package (0.0037) *

I agree, it's a horrible choice of a package name.

Web-Passwd (0.03) ****

This is a nice little .htpasswd management application. I was able to deploy it for a project today fairly easily. It could be more versatile by supporting other config backends besides Config::Tiny, but that's a relatively minor issue-- Config::Tiny is small and has no dependencies of its own. Overall: recommended.


MetaStore (0.22) *

Perhaps there is something useful in here, but I can't tell from the largely absent documentation in the top level module.

The description "classes for multiuser web applications" could use clarifying as well, since I thought websites were generally expected to have more than one person use them....

A "SEE ALSO" section comparing this web framework to existing popular ones would also be very useful.

Test-Deep (0.096) *****

I needed to test that a large arrayref of hashrefs contained a couple elements somewhere in a couple different hashrefs in the structure.

By combining cmp_deeply(), supersetof() and superhashof() from this module, I was able to solve the problem elegantly.

Highly recommended for data structure testing. Don't wait for a complex data structure to try it.

Functions like superhashof() also make it even easier than is_deeply() to write tests for some simple cases.

Exception-Class (1.23) *****

It's a nice system for handling exceptions in larger systems-- it's what I'm using now.

I have some sense there's a way to make it simpler, but it certainly works well enough.

URI-Fetch (0.08) ***

A useful module, but its origins as a feed management tool show through too much. The documentation refers to the content that is fetched as "feed" sometimes, even when it doesn't need to a feed at at all.

It's currently not an attractive tool to mirror image files (or other sizable files with), because it would put the whole file into a Perl data structure and serialize it and cache it that way. Something like mirror() from LWP::UserAgent may be more interesting in that case.

Still, it has some neat features like Gzip support and comprehension of cache-related HTTP headers, and may be worth a look for inspiration, even if it doesn't exactly match your needs.

CGI-Application-Plugin-Output-XSV (0.9) *****

This CGI::App plugin makes easy work of dumping CSV data to the web. This more recent release adds iterator support so data can be streamed to the web without being held in memory all at once. With this feature addition, I consider this plugin "complete".

Good docs and a number of automated tests.

CGI-Application-Plugin-Redirect (0.1) *****

A helpful and frequently useful simplification for CGI::App projects. The stability and functionality is worthy of 1.0, rather than 0.1 for this simple plugin.

Perhaps this functionality should even be in the core of CGI::Application.


Perl6-Junction (1.10) *****

Excellent. Clear docs and code, and plenty of tests. Recommended.

WWW-Pagination (0.35) *

I found the documentation confusing and there are no real tests beyond trying to "use" the module. A SEE ALSO section was also missing, which could explain why this module is considered better than the existing alternatives.

I highly recommend the "Data::Page" and "Data::Pageset" family of paging modules instead, which are mature, well-tested and well-documented.

CGI-Application-Plugin-QueryHash (1.00) **

I gave this distribution fives for everything but a 2 overall, because I dont' recommend it, at least for users. You could do this instead:

%h = $self->query->Vars;


$href = $self->query->Vars;

It is annoying that gives you back null-separated values instead of an arrayref, but multi-valued params needed be handled speciallly anyway (since they are an arrayref and not a scalar). So, it's easy to just use:

@values = $self->query->param('field')

in those cases.

This would be better implemented as a generic mix-in style plugin for query objects, since it works on with any object with a compatible param method. Doing so would require only a couple of lines of code changes and would make the moodule useful beyond CGI::Application.

Parse-CSV (0.02) *****

I tried it on a 70,000 line CSV file and it works great. Fast and easy to use. My only complaint was that I still had to load Text::CSV_XS directly to call the "combine" method, so I could spit back out a CSV row in a munged format. Seems more like a "1.0" release than an "0.02".

HTML-TokeParser-Simple (3.15) ****

I could never wrap my head around HTML::Parser, but I found this alternative easy to use and sufficient for several HTML parsing tasks.

Text-NeatTemplate (0.08) **

Every new templating module should be required to have a "Justification for Existence" section, like this one does. I appreciate that. Overall, the docs are helpful and the justification is somewhat reasonable, but there are no substantial tests for the module right now. I would stick with one of the more established templating systems until that changes.

Chest (0.082) ***

I disagree with David Cantrell's harsh review. The code is OK, although stylized in a uncommon way. There are some tests.

The Synopsis shows how this can be used as part of a simple internationalization system.

The project could definitely use more documentation to explain what it's particularly great it, but I found it decent and novel.

v6-alpha (0.007) ***

Exciting project, but it currently doesn't directly support basic things like a hash definition. However, the pace of progress seems to quick, and I expect we'll see details like that repaired soon. (Hashes are a known issue on the TODO list).

I hope to use it see what's involved in porting Perl5 modules to Perl6.

Best (0.06) *****

A welcome addition to my toolkit. In the past I've written the kind of code that this module abstracts to load the "best" of two modules, like YAML::Syck and YAML.

It's boring code to write, and more difficult to get right on the first try than I suspected. The next time I need to do this, I'll reach for instead!

Test-LongString (0.09) *****

Works great, and is used by other testing modules like Test::WWW::Mechanize, which uses it to test web page content.

Class-InsideOut (1.00)

Data-Page-Set (0.04) ****

I agree with Leo that I would rather this module implemented as an extension to Data::Page. However, I really like that it helps to generate HTML, while still allowing you complete control over final HTML if you want that.

I added an example to Annocpan that demostrates that the interface is flexible enough to allow you to use it in conjunction with a templating system to provide the final logic and HTML code.

It's unfortunate that it isn't named Data::Page::Link, as the current name makes it sound like it is purely an alternative to Data::Pageset, when the focus is somewhat different.

HTML-Defaultify (1.01) *

The module does its own HTML parsing instead of farming out that task, which I see as a weakness. It also has no tests, and hasn't been updated in four years.

I recommend HTML::FillInForm instead, which serves the same purspose, uses HTML::Parser for parsing, has many tests, is widely used and has been updated to handle various edge cases.

DateStamp (v1.0.4) **

In isolation, this module looks OK. The interface is decent, although including "return_" in the method names adds little. The docs and automated tests look good enough.

But this module does not exist in insolation. There are many date/time modules to come before it, including the excellent DateTime suite.
Considering DateTime handles this task and more and is well tested through wide-use, it's hard for me to recommend this one.

The idea of focusing just on returning the current date is interesting, but really what most of this module does is try to make formatting a date easy, and the current date is just a special case of that.

I would rather see the effort applied to this module go into a DateTime formatting module, although I'm not convinced another one is needed.

CGI-Application-Server (0.01) ****

This is a welcome addition to the CGI::Application tool chest, allowing for easier testing and work offline without a full Apache server. Despite the "0.01" release, there looks to be solid tests and documentation and tests for the code that is present, which is already useful.

MIME-Lite (3.01) *****

MIME::Lite has been my standard e-mail generation solution for years. I use it for tasks from simple to complex. Today I noticed another small but important benefit it offers: It strips headers of newline characters, preventing a "header injection attack" when e-mails are generated from values gathered from untrusted sources.

Template-Extract (0.40) ***

This scraping tool is to nice to have in the toolbox, but's no substitute for a deeper understanding of Perl REs. Having been a convenient solution in the past, today Template::Extract fell flat on its face when I tried to use it. Even with the DEBUG option turned on, it just churned for a long time with no useful result.

Accomplishing the same task using regular pattern matching turned out to be simple to write:

my @custs;

while ($html =~ m{/custs.cgi\?id=(\d+)'.*?(PROSPECT|LEAD)-(.*?)\s*</td>}gs) {

push @custs, {

cust_id => $1,

stage => $2,

status => $3,



And it ran noticeably faster! Having compared both styles, sometimes the "old fashioned" way turns out to be simpler and clearer.

But yes, Template::Extract is certainly a neat idea and fun to play with.

FindBin-libs (1.24) *****

A welcome addition to the "FindBin" idea. I primily use FindBin for the purpose addressed here -- to find a perl library directory relative to the script being called. This module allows me to replace:

use FindBin (qw/$Bin/);

use lib ("$Bin/../../perllib");


use FindBin::libs qw(base=perllib);

CGI-Application-Plugin-HTDot (0.03) ****

It works as advertised to integrate the TT dot notation in HTML::Template::Plugin::Dot into CGI::Application.

However, I'm taking a star off as the implemention is now out date with CGI::Application. I submitted a patch to address that last November, which can be tracked here:


CGI-Application-Plugin-Forward (1.06)

I had a hand in this one, so I won't give a formal rating.

This module provides an internal redirect, and I now consider it an integral part of the CGI::Application framework.

It's added value is that it keeps track of the "current run mode" when making internal redirects in CGI::Application.

It works well in combination with the newer feature of load_tmpl() to have a default template name based on the current run mode.

Without the forward() feature, the calculation of the template name after the internal redirect wouldn't work.

It's not essential depending on your application, but for cases like the above, it's exactly the right tool for the job. Some other plugins may already use it internally whether you it directly or not.

CGI-Application-Plugin-AutoRunmode (0.12) ***

This plugin for CGI::Application allows to you skip the step of declaring a "setup()" routine, by making use of subroutine attributes to label run modes instead. I find it to be more concise and clearer as well.

Unfortunately, when using it on amore complex project, I ran into a problems. The first what that it doesn't play well with standard export/importing, but uses its own "Delegate" system to essentially re-implement this. This functionality involves passing an argument to the delegate routines, which I didn't want and had to workaround.

Worse, when I switched to modperl, none of run modes declared this way worked. Perhaps it works for others, but it became clear my own time savings with using this module evaporated, and I took it out of my code.

I love the idea of this module and hope some of the hassles I ran into will be addressed in a future version.

CGI-Application-Plugin-Authentication (0.09) ***

I evaluated this solution carefully and so far have decided not to use it. As with Cees' other published work, it generally feels well designed, documented and tested. For simple authentication, I felt like it was overkill. (It has whole modules to wrap the "uc" and "lc" functions!)

It seems like better fit when authentication needs or more complex, such as supporting multiple authentication methods.

It could also be a nice solution if you haven't designed an authentication system before and want a documented framework for it that illustrates all the parts of it.

The project is admittedly early in its lifecycle, and I look forward to seeing how it evolves.

CGI-Application-Plugin-Authorization (0.07) *****

I'm using this in multiple project and like the overall design.

I would recommend trying it to help with authorization on a CGI::App based project, as the code is accessible and easy to extend if it doesn't have a driver or feature you need.

Schema-RDBMS-AUS (0.01) **

This distribution tries to provide an all-in-one solution for user, group, session, authentication and authorization handling in web applications. Such an all-in-one solution appeals to me, but I have trouble feeling better than so-so about this distribution it its current state.

It suffers from some issues I would expect from an 0.01 release, like missing documentation for the "login" method. However, it does contain a sizeable test suite.

I was interested to see that it used DBIx::Migration, another newer distro which looks interesting, but I was dismayed to find this meant that there were 19 seperate SQL scripts used to set up the schema! This seemed excessive, and made it difficult to browse the data model to get an overview of what was happening at that layer.

One concept concerted me: 'A "Group" is just a user with it's "is_group" flag set.' This looks me like it could lead to a muddled data model once users and groups have a few attributes of their own.

I think the most compelling part of the distribution is the logic developed around managing groups and permissions-- areas which seem less well covered by other modules.

I'd like to see this distribution evolve to focus on this in a way that's easy to integrate with solutions that already cover the rest of the features, such as CGI::Applications Authentication and Authorization plugins.

DBIx-Web (0.60) *

From the volume of documentation, clearly a lot of work has gone into this web/database solution. However, my first impression of the documentation that was full of details, explaining what flags like "-recDel1C" should do, while being short on overview or "marketing" documentation to draw the user in. This, combined with the missing the "Changes" file and lack of substantial tests, I'm not inclined to explore further.

The source code seems to model the verbose but cryptic documentation, making heavy use of difficult to grok arguments-by-index, like this:

length($_[1]) <$NLEN ? ($_[2]||'0') x ($_[3] ||$NLEN -length($_[1])) .$_[1] : $_[1];

Overall, I find this module inaccessible.

Auth-Sticky (0.86) *

This module appears address authenication and authorization for db-backed websites, but has a lot of problems. It only has one test, to load the module, and it will fail because the module name in the test is wrong.

The interface uses "auth" to means "authentication" at times, and "authorization" at other times.

It requires a specific data model, but it doesn't document what the data model is.

It also uses the remote machine address for authenication, which will fail with proxies such as AOL uses. There are no options to /not/ use the IP as part of the process.

I would suggest instead exploring CGI::Session and the Authorization and Authenication and session plugins that are part of the CGI::Application or Catalyst frameworks, or perhaps Authen::Simple.

WWW-CMS (0.86) *

This release includes no documentation, no substantial tests, and from reading the source, it's functionality is largely to re-implement basic templating functionality that is already available in a dozen different ways on CPAN.

For this module to become in a worthwhile CPAN addition in my book, I'd like to see not just test and docs, but a clear statement of its value and niche as a newcomer to a field with so many established alternatives.

YAML-Yaml2Html (0.5) ***

This is a helpful, well-documented tool, but it is not robust-- It supports only a subset of what YAML and HTML can do. For example, it currently lacks HTML table support. I would like to see it develop in the direction of's tag support: Allowing you to create a tag "on the fly". I look forward to seeing it develop further.

Lingua-EN-Numbers-Ordinate (1.02) *****

This module creates ordinal numbers from plain ones ( "3 -> 3rd" ).
I was a little surprised not to find this functionality in DateTime or even the strftime man page. However, I suppose the sticking point is that is language-specific.

Whatever the reason, this module provided a simple function that did the job for me. Except for the long name I'll have difficulty remembering, I'm happy.

Regexp-Common (2.120) ****

This is a very useful module-- I integrated support for it into Data::FormValidator.

However, the overly comprehensive test suite is a pain to wait for. My impression is that the tests go beyond testing this project, and are re-validating that the underlying regular expression of Perl actually works. That seems unnecessary. While I'm for comprehensive testing, I think some simpler is possible here.

Devel-Dependencies (1.00) **

I see little reason to use this when Module::ScanDeps already tackles the same problem space well, including some built-in known exceptions, and the ability to do static scanning or execute the script as well as simpling compiling it.

For this module to be worthwhile for me, it at least needs to explain in "SEE ALSO" why people should bother it instead of the more established Module::ScanDeps.

HTML-Prototype (1.39) ***

So far I have found this module to be a nice introduction to the Prototype library for Perl users. However, I have removed most of the calls to this module that I used. I find it clearer to call the prototype functions directly.

delicious-backup (0.01) **

This will be a nice backup utility, but it needs some polish. It's missing a Config::Auto dependency, so it doesn't install cleanly. For me it generated an empty file, which illustrates that it needs some better feedback functionality.

I look forward an updated version of this module.

HTML-FillInForm (1.06) *****

HTML::FillInForm is a huge time saver for form refilling. It's a key part of the CGI::Application::Plugin::ValidateRM for form validation and re-display.

I give the interface and and ease-of-use some points off because there are simple things to do make it easier to use. In part of because of these weaknesses, the DWIM functionality has been duplicated in plugins for CGI::App and Catalyst which use it.

I explain the details of that here:

DateTime-Event-ICal (0.09) *****

This module computes DateTime sets based on the Ical spec and it does it well. It saved me hours of work with tedious recurrence handling on a calendar project. If you need to handle event recurrence, I recommend following the Ical spec and using this module as part of the solution.

I do have a small niggle with the interface:

But I expect that will be addressed soon.

Sub-MicroSig (0.01) *****

First impression: Very, very nice. I looked through the source and docs to see if there was source filtering to work this magic, but I found none. (Great!). I'm curious to see if there might be a noticeable performance hit compared to Params::Validate or other oddities, but this is definitely a welcome addition to CPAN in my book.

CGI-Application-Pluggable (0.01) **

It's an interesting idea, but it not yet in a state I can recommend. It doesn't have an option to import specific things from plugins, which seems necessary. It also works by modifying @ISA, which is not the usual way that CGI::App plugins work, leading to potentially unexpected results.

CGI-Application-Plugin-ViewCode (1.00) *****

This is a novel and well-implemented development aid for CGI::Application users. This most recent release adds the ability to easily review the POD as HTML for loaded modules. By integrating with the DevPopup plugin, it's easy to review the documentation for the run modes that are executing. Well worth a try!

CGI-Application-Plugin-DebugScreen (0.04) *****

A super easy to use replacement for the "Internal Server Error" screen for CGI::App users. This alternative provides a back trace with context, making it easy what led up to the error. The design of the page can be changed through a template. This latest version integrates with the ViewCode plugin. When a pending patch is applied, you'll be able to jump directly to a syntax-highlighted view of the code and go right the failing line. I'm bumping up my rating to five stars.

(disclaimer: I wrote that pending patch...)

Perlcast (20051209) *

Huh? I'm not sure I feel about having interviews distributed as Perl modules, I couldn't find a transcription in this documentation anyway. It seems like there's been a mistake...

HTML-Template-Compiled (0.58) *****

I have a very favorable first impression of this module. It deviates from HTML::Template's API in a few ways, such as removing die_on_bad_params and adding a dot notation like TT's. I like those changes. I ran the included "" script and found that on my system it was repoted to be about 5 times faster than plain HTML::Template, and about 10 times faster than Template Toolkit. (Others have reported that with some tweaks the advantage may be merely 3 times faster under mod_perl).

DBIx-DBH (0.09) ***

At first glance this module suite may be appear to be overkill for the simple task of configuring a database connection. For building one static connection, it is.

However, I think it has a place within frameworks and distributed software that needs to configure connections in several different ways.

I would consider it improvement if it dropped the 'connect' and 'form_data' methods, as the real meat is in the connect_data() routine.

Devel-SimpleTrace (0.06) ***

The easy benefit this module offers is providing a backtrace with filenames and line numbers when your code warns or dies in an eval block.

However the current API is only suitable for development work in many cases, because it globally overrides the 'warn' and 'die' signal handlers.

A more production-compatible solution can be accomplished with the Carp module, and localized handlers like this:

use Carp;


local $SIG{__DIE__} = \&confess;

eval { ... }

Unless you really prefer how this module formats the output, I recommend the safer syntax of Carp above.

EvilBoss (1.01) *

No documentation, no tests, and a name that leaves you guessing what the heck it does. I checked the source of one of the modules, and there were no useful comments, either.

HTML-Template-Pluggable (0.12) ****

HTML::Template::Pluggable bring extensibility to HTML::Template that should allow for more compatible extensions.

HTML::Template::Plugin::Dot adds support for Template Toolkit's dot notation, taking a way a major reason why HTML::Template users make the switch.

The project is not done yet, though-- some more hooks need to be added to complete the plugin system.

The interface is easy to use, and already has attracted third-party support for two different CGI::Application plugins for even easier integration.

( disclaimer: I contributed some to this project although I think Rhesa has done most of the work. )

Text-QuickTemplate (0.04) **

This module claims to be a "lightweight" alternative to existing templating system, but doesn't bother with many details of why they are overkill, and why the other lightweight options are insufficient.

At the same time, it adds some less common features: defaults, "override values", sprintf formatting, and a special exception handling system.

In whole, it is Yet Another Templating System with it's own benefits and drawbacks, which in my opinion we sorely don't need without a clearer understanding of what's wrong with the existing alternatives.

I would rate this module higher if it had an expanded SEE ALSO section that better explained when it is expected to be a better choice over the the established alternatives.

Data-FormValidator-Constraints-DateTime (1.03) ****

An excellent example of a "plug-in" for Data::FormValidator, this module helps
to validate dates in common formats and return them as a useful DateTime
object, making it potentially more useful than the built-in date validation

It provides a great example of the more pleasant 'constraint_methods' syntax
available with DFV 4.0.

(disclaimer: I maintain DFV, but am not directly involved with this module's

Test-MockObject (1.00) *****

This was the perfect tool to help test the upcoming HTML::Template::Plugin::Dot module, which allows chained accessor calls to be referenced in a template, like TT does.

We needed to test lots of method calls, but not for any particular module. Making generic fake objects was very handy and fast with this module.

Kwiki-ShortcutLinks (0.03) *****

This module was easy to install and configure and worked as documented. I find it very useful. My favorite shortcut was this one:


Which allows me to link with perl documentation for a module with just:


Apache-ConfigFile (1.18) **

I was able to parse my config file easily enough with it, but the ability to write files is missing, severely hampering the usefulness of the module. Considering it hasn't been updated since 2001, I'm not going to hold my breath. It also doesn't have any real automated tests.

I'm currently evaluating Apache::Admin::Config as alternative which at least appears to have the ability to write files includes a test suite as well.

Data-Lazy (0.6) *****

This module "just worked" for me. I realized I had a testing library that was creating a database handle for every test script whether it was needed or not. With Data::Lazy, it was easy to only create the handle if it was needed by making the a change in one place.

PodToHTML (0.05) **

It's a nice module, but has an old and simple bug that will prevent it from working for many people. There is a name conflict with "Pod::Find", also located in the "Pod::Parser" distribution. Until one of them renames their module to avoid this issue, the 'podtohtml' script won't run.

Kwiki-Spork (0.11) **

It's not especially useful without a synopsis or a description.

PerlMagick (6.17) **

Image::Magick is a powerful image processing tool and handles many formats. I have used it for making thumbnails and rounding the corners of images.

On the downside, it is significantly under-documented, and the ChangeLog file in the distribution stopped recording recent changes many versions ago. I have also experienced a number of a regressions with Image::Magick-- features quit working after an upgrade. Twice the functionality to created rounded corners has silently broken. Another time a particular kind of JPEG starting Image::Magick to run indefinitely. Yet another time, a trivial syntax change was needed after an upgrade which could have been avoided. Perhaps most seriously, it appears that after upgrading to 6.1.9, there was a bad memory leak that effectively took down a busy mod_perl enabled website which used it.

For these reasons, unless you need some cutting edge feature of Image::Magick, I recommend the Graphics::Magick fork. In my own testing, no code changes were needed besides the name change. Graphics::Magick has a focus on being more stable, and I believe it includes more automated tests in it's distribution.

Graphics::Magick is not on CPAN yet, but there are pre-made packages for many platforms that include the Perl module has part of the package.

SQL-Interpolate (0.30) *****

Using bind variables is important when creating SQL statements because they provide protection against SQL injection attacks. SQL::Abstract made a worthy effort to generate SQL and bind variables, but failed to handle complex cases, as well as using a syntax that could be unintuitive.

SQL::Interpolate is a next-generation solution for SQL generation with a perfect balance of expression between direct SQL manipulation and Perlish shorthands. You can use as much direct SQL wherever you like with SQL::Interpolate, making easy work complex 'WHERE' clauses with combinations of nested 'AND' and 'OR' bits.

It has abstraction levels to suit most anyone's tastes. You can simply generate SQL and bind variables if you like. You may also use it as a value-added wrapper around DBI. For the adventurous, a source filtering option is available, providing the easiet interface, at the risk of difficult to track bugs.

David Manura has been very thoughtful about the design and production of this module. Although this is the first release, I would declare it a "1.0" release myself, rather than the modest "0.3" David has assigned it.

Highly recommended for SQL generation.

(disclaimer: I contributed to this module, and to SQL::Abstract before I found this one. )

Test-TempDatabase (0.02) *

This module has poor security that can be avoided. It makes system calls from the user input without any validation:

`createdb $db_name >& /dev/null`;

The same thing could accomplished easily without using a system call. ("CREATE DATABASE" can issued from within DBI and has a chance of being portable).

CGI-Application-Plugin-Stream (2.00) *****

This module helps with the slightly tedious task of streaming files to the browser with CGI::Application. (An example would be a PDF you generate on the fly). It makes two key parts dead simple: It takes care of streaming the file in little chunks, and figuring out the MIME type to send as the header for the file.

(I contributed some code to this module).

CGI-Upload (1.07) ****

This module offers a simple and consistent file upload interface that works with, CGI::Simple, and potentially other modules. It also offers an easy interface to the mime-type of the uploaded file, detected using File::MMagic.

Recently, a strong test suite has added as well.

I think it's most useful for people who are writing file upload systems that they might want to work with multiple modules.

Otherwise, it may be simpler to use use the upload routines already built-in to those modules, and call File::MMagic directly.

CGI-Session-BitBucket (1.0) *

This module doesn't really do anything. It's supposed to be used as a placeholder until you decided on a "real" CGI::Session interface to use. This would make sense if you had to set up a complicated database or other backend to store sessions. However, by default CGI::Session easily stores files in a "tmp" directory. Usually, zero configuration is required for this. As a CGI::Session user myself, I just don't see the need for this module.

HTML-DBTable (0.05) **

Insufficient documentation is provided to actually use the module (without reading the source code).

MiscUtils (1.0.0) *

The functions seems somewhat useful, but a "misc utils" collection is often hard to find, and well, collections of mostly unrelated functions don't seem that useful to me. I would much rather see these functions added to existing modules, or exist as their own specialized utility modules.

The 'mkdirs' function re-implements functionality which has been provided by File::Path::mkpath, which has been in the Perl core since 5.005. I figured that out by searching for 'mkdir' on and reviewing the first 3 pages of results.

HTML-HTMLDoc (0.07) ****

This module worked great for me. I was easily able to use it to generate a PDF file. I was also happy to see that that the documentation contained a tip to allow it work under mod_perl. Before I found this I made system calls to the 'htmldoc' binary. With this module I no longer have to bother with managing temporary files myself.

HTML-FormFiller (0.04) *

The module appears to offer no significant benefit over the much more established HTML::FillInForm. FillInForm also has a much more thorough test suite as well.
This module makes the claim that it doesn't have the dependencies on "CGI/modperl" that HTML::FillInForm does. This is a false claim. FillInForm does not require CGI or mod_perl to be installed to install or use the module-- A vanilla hash will work just fine as data source. In fact, FillInForm only requires Perl 5.5 to work, while this one requires 5.6. It also depends on HTML::Parser and HTML::Entities, which were not properly declared in the Makefile.PL. I recommend using the old standby, HTML::FillInForm instead.

IO_CSVHeaderFile (IO_CSVHeaderFile_0.02) *****

All I wanted to do was to turn a CVS file into an array of hashes. Seems simple enough. This module performed the task as easily as I could have hoped. I first wrestled with DBD::CSV and then tried Tie::Handle::CSV. The latter didn't work because the hashes it produced were really blessed objects. By contrast, this simple module 'just worked'.

It's a good thing, though, because it doesn't many options to configure how it works.

Data-Page (1.01) *****

This is my favorite paging module. Before I found it, I had rolled my own, and tried to use HTML::Pager a few times. Realize that most of the time, you probably want to use "Data::Pageset", a sub-class which handles the notion of dealing with groups of pages. At first I thought the module was "too simple". Once I tried it, I found the level of functionality it provided was "just right".

CGI-Utils (0.06) **

Creating a 'light' without the HTML generation functions is a an admirable goal. However, it seems CGI::Simple has already done an excellent job at this. CGI::Simple runs much of the original test suite, insuring a high degree of compatibility. CGI::Utils, by constrast, has relatively few tests, and appears to be using none of the original tests. It appears some function names are different without great reason. For example, The "escape" function from is named: "urlEncode". So I would consider using CGI::Simple instead.

CGI-NeedSSL (0.02) *

I don't think this module adds sufficient additional value to merit using. It requires, which already has an https() check built in. It's primary function is just a simple wrapper around that:

sub cgi_is_via_SSL {

return 1 if $query->http('HTTPS');



I believe with, taking action based on whether or not HTTPS is in effect is quite easy:

if ($q->https()) {


It's actually less to type than using the wrapper. :)


could just be:

croak unless $q->https();

HTML-GenToc (2.10) *****

This module installs with a very handy tool called "hypertoc", which is useful for generating automatic Table of Contents for HTML files. It makes a nice complement to the "podtohtml" utility (Not be be confused with pod2html). PodtoHtml does a good job of processing whole directories of files, but the resulting pages don't include their own Table of Contents pages. It's easy to add them with hypertoc:

find /doc/output/dir -name '*.html' -exec hypertoc --gen_anchors --gen_toc --overwrite --inline {} \;

Business-PayPal-IPN (1.94) ****

It Just Worked. I couldn't really ask for more. Actually, I could ask for a little less. :) It provides an OO interface, which just makes method names from the hash keys that IPN has returned.

It seems to me that this could be removed from the docs and code without a loss of functionality-- accessing the hash directly is easy enough.

DP-Perl (0.101) *

This module has a vague and name description. It says it offers "several extensions..." to Perl, but all the functionality it offers is from a single function with one active line.

Log-Easy (0.01.2) ***

I'm improving my rating of this module because some documentation appeared. I would change the overall rating to be "undef" if I could...because I haven't tried it out directly myself. I'll leave it at 3 instead.

DBD-Pg (1.31) *****

I've been using DBI/DBD::Pg exclusively for years as my Postgres access method for Perl. It works and works well. (Disclaimer: I'm a minor contributor to the module).

A new release of DBD::Pg is out and I'm upgrading my rating from 4 stars to 5. It has a number of bug fixes, performance improvements and feature additions, as well as stronger documentation, and about 100 new tests since the last release, if I recall.

I'm very happy with it.

Test-Harness (2.36) *****

I love the new 'prove' testing tool. It's a great help when developing and testing. For example, it makes it easy to be "verbose" when making tests, and to pick out just a few tests to run. Like this:

prove -v -b t/01setup.t t/15specific_test.t t/99cleanup.t

It's much more convenient for me than trying to do the same thing with "make test".

List-Compare (0.21) *****

A well documented and easy-to-use module for comparing arrays. Even if this module doesn't do what you want, It's thorough review of similar modules in the documentation will send you in a useful direction.

Test-Reporter (1.20) ****

This module supplies the 'cpantest' binary, which makes it incredibly easy to submit test results to the CPAN testers project. I think the documentation could be a little more explicit, providing a direct example of the process, but it's still quite reasonable to figure out as it is.

I look forward to this tool being more widely used, so we can better guage the overall quality of modules on CPAN.

DBIx-Abstract (1.005) ***

The primary benefit of this module is the ability to express SQL syntax in a Perlish way. This makes for handy shortcuts for 'WHERE' clauses, as well as inserts and updates.

However, the module does too much beyond this-- It has a number of functions which are simply wrappers around DBI calls, adding needless complexity. While this module is handy for quickie "INSERT" and "UPDATE" statements, I find SQL::Abstract is a cleaner, simpler alternative. SQL::Abstract focuses soley on generating SQL syntax from Perl syntax. This gives you more control of your interaction with DBI, and makes for code that is easier to debug.

only (0.26) *****

This module addresses the increasingly common situation of wanting to have two
versions of the same module installed. This would allow you to keep the old
version to support legacy applications while using the the new features of a
new version in a new project.

Util (0.07) *

While some of these functions could be useful, I would never think to look for them in package generically named "Util". I would much rather see the functionality here supplied elsewhere (in more specific packages) or integrated to existing modules.

HTML-Paging-SQL (1.13) **

I would generally not recommend this module for paging your data. It embeds HTML in which restricts your options when presenting the paging interface. This distribution includes no substantial tests to confirm it's working. 'use strict' is not used with the code. It really doesn't do anything with SQL either, as the name suggests. It just returns "LIMIT" and "OFFSET" values, which could be used in non-SQL applications welll.

Instead, I recommend the more flexible Data::Page and Data::Pageset modules. I use them to page SQL data in HTML, but they would work fine in other cases as well.

Mail-SpamAssassin (2.55) *****

I use Mail::SpamAssassin to filter my spam. It works incredibly well. It rarely ever misfiles anything, and even worked very well in the beginning with little training. I use it with Mail::Audit for a complete perl-based mail filtering solution.

Crypt-OpenPGP (1.03) ****

Crypt::OpenPGP provides a pure-Perl, well documented, easy to use interface to encryption services such as GPG. I can't currently give it a full five-star rating, because I still sometimes experience an odd bug when encrypting that I haven't been able to fully solve yet. :)

Still, if you are using to encrypt or decrypt with a PGP-like system from Perl, this module is my current primary recommendation.

GnuPG (0.09) ***

This module has a easy critical bug that hasn't been addressed in over a year (bug 1364). I found its 'easy' interface to GPG using a 'tie' a little awkward as well. When this module first came out, it seemed like the best solution for accessing GPG from Perl. Now I think there are better options to try first, such as the pure perl Crypt::OpenPGP, which has a much more straightforward interface for the same task.

CGI-Session (3.95) ****

After creating my own website session management system, it was refreshing to find CGI::Session which encapsulates a number of the the 'harder' parts of the problem space into a simple and easy to use interface. The documentation for the module is excellent and thorough.
A number of databases are supported, including the possibility of using flat storage. This helps to make applications using CGI::Session even more portable.

My only complaint about the module is that it stores a big Perl data structure in a SQL data field, instead of storing the data using standard SQL techniques, which would allow more flexible access.

I've written CGI::Session::PureSQL to address this, which I hope to get around to polishing and releasing Real Soon Now.

SQL-Abstract (1.13) *****

SQL::Abstract is a nice alternative to the DBIx::Abstract module for providing a more Perl-like interface to creating SQL statements. Unlike DBIx::Abstract, SQL::Abstract does not use the database handle at all. It simply parses a Perl data structure and returns a SQL statement and appropriate bind variable.

This design gives you more flexibility to do something like a "prepare" a stement once, and then execute it over and over. This means that for something like doing a lot of inserts, SQL::Abstract can be exponentially faster than DBIx::Abstract.

I use the module for quickly creating large INSERT and UPDATE statements, as well as creating particular kinds of WHERE clauses.

HTML-Pager (0.03) **

I'm a big fan of HTML::Template, so I thought I would like this module to create HTML page numbering, which is by the same author and built to play nice with HTML::Template. With several attempts at using it, I continued to find the interface for it confusing. Eventually I found it unsatisfactory anyway because it dictates some of the HTML design on the page (See bug #2471). I recommend Data::Pageset instead, which has an easier to understand interface, and does not try control any of the HTML output.

Data-Pageset (0.06) *****

Data-Pageset works great as centerpiece in a paging solution, such as adding page numbers with 'previous' and 'next' links to a web application. In the past I looked at HTML::Pager and 'rolled my own' solution a number of times. Data-Pageset is simple to use and understand, and allows me complete control over the resulting HTML unlike HTML::Pager. See also 'Data::Page' for simpler cases and 'Data::Pageset::Variable' for more complicated ones.

Data-Grouper (0.06) *****

This is a very useful module that helps translate data structures between what's returned from a SQL table via DBI, and the kind of structure you need to represent a nested loop in HTML Template.
I use it commonly for that problem-space. Just check out the 'Lazy' section in the documentation.

It's probably better versioned as "1.0"-- I've found it's already stable and has a useful and working feature set.

Test-DatabaseRow (1.01) ****

I've used this module and found it works well. I find I have to double check my syntax a little more often than I'd like, but I'm still somewhat new to use it. It seems like it could have a little easier interface, but it's not clear to me exactly what that might be. :)

WWW-Mechanize (0.59) *****

I use WWW::Mechanize to automate testing of web applications, and find it very useful for that.

It is still in a development phase, which means there are still frequently non-backward-compatible changes being introduced. Still an excellent module overall.

ExtUtils-ModuleMaker (0.32) *****

Although I just filed a bug report against this module (#3326), I'm still giving it a 5 star overall rating, because it's such a refreshing alternative to the old "h2xs -XAn" method of generating a module skeleton. Using the included 'modulemaker' binary, it's possible to answer a few easy questions and have a nice module distribution generated for you...without having read any prior documentation. It's even compatible with the newer and hipper Module::Build method generating modules.

Let's flush out the few bugs and kinks in this system and put h2xs to rest as the primary recommendation for module skeleton generation.

Data::FormValidator / Data-FormValidator (3.12) *****

Disclaimer: I maintain this module. I find it's the best choice for validating forms, especially on the web. It's well suited for form validation jobs from simple to complex.

WWW-Auth (1.00) *

It's lacking POD documentation, making it hard to understand and use. Including some tests in the distribution would be nice for Quality Assurance as well.

Email-Filter (1.0) ***

A very nice module. However, I'm still using Mail::Audit instead because this module contains a scary data-loss bug:

Besides that, I'd like to see a more complete test suite, and some minor POD bug fixes. That's why I'm rating this "3" and not "5"

HTML-Template (2.6) *****

This module enforces a useful seperation of code and design by providing a minimal amount of template logic in the templates. Easy to learn, built for speed, and very powerful. I use it quite frequently, even as template solution for non-HTML text. It is mature, with several extension modules available, plus ports to several other programming languages. Highly recommended.

CGI-Application (3.1) *****

An excellent framework for web applications. I have been using it for over a year and highly recommend it.

xsub (1.0) *

There is no documentation or test script included with the distribution. It also uses a top level namespace when it doesn't appear to be warranted. It also uses a an all-lowercase module name, which are typically reserved for pragmas.