Reviews by Robert Rothenberg


Test-Perl-Critic-Progressive (0.03) ***

This is a great idea, except... when you've changed the code and introduced poly violations, you just get a list of how many violations are in your code. There's nothing to indicate which file or where in a file each violation is.

CPAN-Mini-FromList (0.02) *

There are syntax errors in the minicpan-fromlist script that it installs, mainly due to "use strict" violations.

Data-Validate-Email (0.04) ****

Easy to use, works straight out of the tin, etc.

However, it doesn't accept sub-addresses as per RFC 3598. There's been a bug report about that issue since August 2009.

Video-Xine (0.18) *

Missing explicit mention of prerequisites like Params::Validate, List::MoreUtils and X11::FullScreen.

Examples in synopsis are broken: it's not clear where variables come from, or there they are lowercase in one line and uppercase in another.

Even when all that is sorted, and the program runs with no errors, no window is displayed showing the video.

Considering that it's not been updated in almost two years, I've given up on it.

Math-Numbers (0.000000001)

FYI, "Bluto's Algorithm" is just another term for brute force.

There are several other packages with similar functionality (primality testing, GCD, etc.), but the documentation doesn't explain how this package is different or better than other packages.

HTML-Strip (1.06) *****

I've not looked under the hood. But it seems to work well and strip the markup from websites. So I'm satisfied with it.

Lingua-Identify (0.23) ****

It's very easy to use, and works out of the box within a few minutes. Not so well for short pieces of text, but enough to be usable.

Algorithm-MarkovChain (0.06) ****

I got it working out of the box within a few minutes, which saved me a bit of time coding the same thing. It seems to do what it says in the docs (from a superficial skim, anyway).

Net-Twitter (3.04002) ****

It's fairly easy to use, subject to the limitations of the Twitter API. I was able to hack a script that interfaced with it quickly.
My only grumble is that it doesn't support proxies, but I can get by without that.

Data-Random (0.05) *****

I haven't looked under the hood, but it (Data::Random::WordList) did what I needed, so I didn't have to write the code.

Moose (0.68)

I'm ambivalent about it: I love powerful extensions to the language like this, but I cringe when I hear a hard drive churn just to load all of the prerequisite modules.

String-Urandom (0.04)

Nitpick: data from /dev/urandom isn't "truly random" but data from /dev/random is.

Term-Shell (0.02) ****

This module makes it very easy to have a working prototype shell application running within a few minutes.

My only nitpicks are that it expects methods to have names that match their commands (e.g. run_command) rather than using an initialization method, and that the the summary/help/execution functions for each command are separate functions. But these are minor.

There's a few other things I'd like, such as password input methods (esp. one that works with Term::ReadLine::Perl), and better documentation on how/where to save data for my method in a way that won't interfere with the internals of Term::Shell.

xchar (0.2) **

It lets me do some simple queries about top-level windows, but is missing a lot of details (like what desktops the windows are in). And it requires Perl-Tk! The documentation wasn't helpful, either. (But the problem with X11 programming is that there's so many technical details...) I opted to use wmctl from the shell instead.

Gtk-Perl (0.7009) *

No documentation except a README and some POD for the color selection button.

Convert-Color (0.02)

Graphics::ColorObject already allows for conversions between color spaces.

The name-to-color conversion functionality of Convert::Color::X11 already exists elsewhere on CPAN (and has so for a long time), notably Graphics::ColorNames (which I wrote) as well as Color::Library and Color::Rgb. All of them support X11 color schemes, and the first two of these modules allow plugins to add new schemes, such as for Convert::Color::VGA.

I'm fine with different modules on CPAN doing similar things differently, but I do think it's important for newer modules to refer to existing modules in their documentation, and explain how their modules are different and better suited for some uses.

Gnome2-GConf (1.044) **

I'd like to write a script that can query the subkeys of a given key, and use that information to pass some options to the relevant program.

For the life of my can't figure out how, or even if it's possible with this module (or the GConf libraries that it uses...), because it's so poorly documented. So a neutral '3' stars.

But -1 star, for the lack of tests.

Edit: I've since figured out how to query subkeys, but it involved reading the Gnome library documentation to find that there is the oddly named "get_all_dirs" function to do this, and then reading the source code of one of the XS files in this distribution to find out that it indeed has an undocumented "get_dirs" function that does what I needed.

CGI-Application-Plugin-Session (1.03) ****

Seems to work as advertised. I'm unclear if there's a way to use CGI::Simple instead of CGI for CGI::Session, though. And I also wonder if $app->session->param() should just override $app->param().

perl-ldap (0.39) ****

I managed to get a simple search query up and running quickly. It's a little bit complex (and I do with there were a few more examples and utility routines to do seemingly simple tasks), but that's more do to myself being new to LDAP.

MIME-Types (1.26) ***

The object-oriented interface is a bit cumbersome, e.g. $type = (MIME::Types->new)->type(shift).

I don't understand the relationship between the MIME::Types and MIME::Type modules: they seem to have the same POD.

I just want to be able to get a MIME-Type from an extension, and to get a list of extensions associated with a MIME-Type.

A bigger annoyance is that the list is rather small.

I wish it could give a "common" extension for MIME-Type (in particular, a 3-character extension), so that I can use it for normalising file names.

Moaning aside, I was able to get what I needed from it quickly.

Edit: I have since written a module Media::Type::Simple that takes care of my moans...

Path-Class (0.16) ****

This is an excellent platform-independent layer over File::Spec.

One (minor) downside is that it doesn't seem to have a way to update objects. So instead one must do something like $path = $path->parent. (This is fine if you don't want side effects, but then why are you programing in Perl?)

Other minor annoyances: (1) a method to extract file extensions (2) untaining.

self (0.15) *****

Wow. Simple, bareword names for "self" and "args" without filters or dodgy interactions with Perl internals. I'm a believer now....

CGI-Application (4.21) ****

Although I've only used this for simple web applications, it's easy to use and you can get up-and-running within an hour after reading the documentation.

I also like that it's easily to override default modules to use whatever CGI or templating module that you'd like (e.g. CGI::Simple or Template).

My only quibble is that the interface seems slightly cumbersome.

Net-PingFM (0.3) ****

It's easy to use, and seems to do what it says on the tin, which is to post to (and let post to other networks for you). This is damn convenient for updating to various blogs and social networks using one interface.

Annoyances: it calls the different keys that's API requires by different names than, though I'm unsure if that's due to API changes by or not. (Their own documentation isn't so clear on this.)

More annoyances: the online tests use a psychotic amount of dependencies.

Net-Google-GData (0.01)

hanenkamp: look closely at the source code, it's clearly more than a stub.

Date-Simple (3.02) ***

Another lovely date module for converting between ISO and other formats. Again, it only handles dates, not dates and times. So useless for my needs.

Date-ISO (1.30) ***

This would be perfect for my needs, except that it only handles dates, note dates and times. So it's useless to me.

Math-Polygon (1.00) ****

I needed a function to determine if a point is inside a polygon for some elaborate server-side image maps. Perfect for my needs.

My only quibble is that the documentation doesn't explain which of the two or three algorithms that it uses. (For some purposes, the method used may not be accurate enough.)

Image-ExifTool (7.30) *****

It does what it says on the tin: read and write different kinds of meta data from images. And it does this well. It also includes a useful command-line utility for viewing or setting values.

String-Approx (3.26)

I don't see anything wrong with a program dieing on an error. It's just as easy to trap that with eval and respond as it is to check a return code. And if anything, it's *safer* to die if there's an error than to continue as if nothing's wrong.

Module-Changes (0.05)

The Changes file has traditionally been a *human*-readable file. The last thing somebody expects when reading a history file is to see YAML. Yuck!

If you want to have a machine-readable change history, use a different filename like "Changes.yml". And generate a human-readable file from that.

Additional mini-rant:

A machine-readable Changes file won't solve the problems that it's intended to. There's no guarantee that a change marked as "security fix" or "bug fix" won't break your system anyway by introducing new bugs or fixing ones that you thought were features, nor is there a guarantee that the author tagged changes correctly. And if a security fix is mixed in with API changes, then you can't separate the two.

If you're so concerned about updates breaking your system, then you're a fool to rely on automated tools in Perl. Read the Changes file, look at version diffs, test on a different server before upgrading. (This is what a responsible sysadmin should do anyway.)

Or better yet, don't upgrade if you don't have to.

ShipIt-Bundle (0.02)

Nitpick: Should be called Bundle::ShipIt. (If nothing else, automated testing tools can ignore it.)

Acme-Tiny (0.4) *****

5 stars for p***ing people off. It's an Acme module, afterall. And an excellent example of one, too. If you don't like these modules, just don't include the namespace in your personal mirrors.

Carp-Always (0.09) ***

This module hasn't really explained why it is better than carp: it traps the DIE and WARN handlers so that the carp "longmess" stack traces are always used. That should be made clearer. Which is nice, but...

The docs state that the current version doesn't play well with other modules that change the die/warn handlers. This is something that can be fixed easily. (It's done in Win32::EventLog::Carp -- which I wrote -- for instance.)

I'm not sure that I like warnings to always be verbose, though.

Date-Tiny (1.03) ***

The rationale for this tiny date module is that since it's hard to get date manipulation right, we won't do any date manipulation at all. This limits the usability of this package.

Maybe some simple manipulation functions (as long as their limits were documented) would increase the rating. (These could be auto-loaded so as to keep the core "tiny".)

That said, once I've parsed a date into year, month and day, I don't need to manipulate it much. (One can use stringified dates to compare them.) So I wouldn't call it useless at all. It's just that the OO interface might be too much overhead for something simple.

It does fill a need though: DateTime takes a long time to load and can be like using a sports car for local errands.

Tie-Hash-Sorted (0.10) *****

I've not made use of any special features, but when you need a hash that is always sorted when you iterate over the keys, it's simple matter of tying the hash and forgetting about it.

Net-ARP (1.0.2) *

The function for looking up the MAC address of a device by an IP address just doesn't work.

You are better off using a system call to arping on a system that supports it.

Tie-Sub (0.05) ****

Tying a subroutine to a hash is a simple thing to implement, but it is nice to have it already done. It works just as it says.

Only thing lacking is the use of the STORE method to pass additional values to the subroutine. However, I don't need that feature, and I can understand why it would make the program semantics weird (but then again, the joy of Perl is in making things weird).

Text-Aspell (0.09) *****

It has a nice OO interface, seems well-documented, and seems to do what it says very well.

LaTeX-Parser (0.01) *

Last updated in 2000 as a 0.01 release. Poorly documented. There's no explanation of what the format of the parsed content is. So I won't go near it.

LaTeX-TOM (0.8) **

This seems pretty easy to use, although I had to re-read the documentation to understand how to use it. The docs lack sample code.
It lacks tests. It needs at least some tests!

It doesn't try to decode accented characters or symbols, which is great because I can throw them into TeX::Encode if I need to.

My gripes are that the plainText method assumes it's given a full document (inside document environment anyway) and that it can't do serial parsing (e.g. I feed it a line, get partially parsed output, feed another line, etc.). But there are easy workarounds for this.

A serious gripe is that it doesn't recognize some forms of math mode, using $..$ or $$..$$. That will require me to write a workaround. Grr.

I find the distinction of types between Trees and Nodes to be unnecessary. It also uses a hack to guess the arguments for a command (assumes argument is not separated by whitespace form command and that groups following commands are arguments) rather than using known or common commands with set numbers of arguments.

Still, I've got some high expectations for this.

UPDATE: it tries to be too smart in it's parsing, and so cannot parse commands for special packages or custom commands. I wanted to write a script that converts markup for one package into another. May as well write my own parser.

Lingua-Ispell (0.07) ***

Grr. No tests, and it failed because it wanted to run /usr/local/bin/ispell rather than /usr/bin/ispell.

Net-Dict (2.07) ****

Looks like a bit of fun to play with, but it's got some minor problems:

The dict script requires AppConfig::Std, but the Makefile doesn't require it during install.

It fails some tests. Not sure why, if it's because the server had changed, or if there's a genuine problem with the module.

HTTP-Recorder (0.05)

No comment about this specific distribution, but about specific reviews:

* Usage advice, tips and tricks, etc. belong in or

* Bug reports belong in

If there are quirks that make it hard to use, or bugs, then they are certainly worth mentioning in the review. But the gorey details belong in appropriate forums, not reviews.

--Rob (at the risk of having this review marked useless)

Time-Fuzzy (0.30) **

For starters, in the description, "Nobody will ever say ''it's 11:57''. People just say ''it's noon''." Well, no. People do say ''it's 11:57''. They also say "it's almost noon", "it's about noon", or "it's just after noon", etc.

I'm not sure I agree with how time is divided up: the source code says hours 0-4 are night, and 5-7 are "early morning", for instance. Hours 11-13 are "noon", but I'd hardly call 11:01 or 13:59 "noon". Those distinctions are rather subjective.

People in the English-speaking world have different ways of describing time. In some parts of the world, people will say "half past one", others will say "half one", or "bottom of one". Or they'll say "quarter of one" or "fifteen minutes before" in place of "quarter to one".

My (albeit limited) experience is that people are so used to regional dialects with respect to time that "quarter to one" is not always universally understood as "12:45".

It's an interesting idea for a module, but the problem it's meant to solve has a lot more complexity than it can handle.

Nitpick: it belongs in the Lingua::EN namespace, since it converts time to a natural language string (English).

Math (0.525) **

Aside from defining functions that already exist in core Perl (why?), this includes other Math::* packages for representing and manipulating colours, vectors (why separate modules for 2-, 3-, and 4-d vectors?) and image sizes. So it probably belongs in the Image or Graphics namespaces.

However, I'm unsure what this package adds in terms of functionality to anything. The SEE ALSO sections generally refer to other packages in the that distribution, than to anything else on CPAN.

It makes a reference to asking the author about adding holidays to Date::Holidays::AT which is by a different author. Odd.

Acme-Placeholder (0.04) *

While I appreciate a good sense of humour, this is just counter-productive, since it singles out the ills of a specific author. In a year's time, most will forget wha tthe joke was about, and it will just grab more namespace.

File-Recycle (v0.0.1)

Two namespace grabs by the same author, File::Trash and File::Recycle, for basically the same functionality. Why?!? (As someone who bothered to bring up the topic on the module authors list and reserve a namespace for a module with similar functionality, this is irksome.)

File-Trash (v0.0.1)

Two namespace grabs by the same author, File::Trash and File::Recycle, for basically the same functionality. Why?!? (As someone who bothered to bring up the topic on the module authors list and reserve a namespace for a module with similar functionality, this is irksome.)

XML-Tiny (1.03)

The documentation is pretty explicit that it supports a subset of XML, and it's pretty explicit as to what that subset is. Presumably for cases where you are in control of the XML, this will do fine.

That said, I usually seem to be working on systems that already have some other XML parsing module installed, so I've not rarely had need for a lightweight alternative. So I've never had to the chance to use it for anything serious.

PerlBuildSystem (0.43.290)

The README and license.txt are POD, not plain text.

The license is absurd:

"You are forbiden [sic] to use PBS if one of the following applies to you:

* You belong to any armed group (inclusive any nation's army).

* You work for (or are) an armement [sic] designer, constructor, producer, or saler [sic].

* You, are part or, work for an entity that directely [sic] produces work or goods for any of the above."

Typos aside, this license excludes most major corporations (including software corporations) which have some connection to the arms industry, citizens of countries with universal military service requirements, people who work for any national government, and employees or students (who are a "part of") of a major university (as most have grants for some kind of arms research).

XML-Parser (2.34) ***

I do with there were examples in the documentation (*), but I was able to write a simple parser to do what I needed in about 15 minutes.

The Tree, Subs and Object modules look like they might make my life easier by putting everything into hashes, objects, etc, but they are so negligibly documented that it's just easier to write a Parser as I know what it should do, versus hacking with dumps of data structures to interpret what is going on.

(*) at least as viewed in, I didn't poke around very much or look closely at the samples subdirectory in the distro (shouldn't it be called "eg"?)

UNIVERSAL-can (1.12)

I don't like packages which do things in the UNIVERSAL namespace much, but I'm not going to refuse to use a package just because the *tests* (not the running module itself) use it.

In the case of Catalyst, the dependency on Test::MockObject has been removed in the latest version.

Regexp-Common (2.120) ***

I needed a handy Regexp to strip some comments from a JavaScript program and found them here. Works great. My only concern (without looking at the module internals) is that I've got a lot of unused Regexp's for other comment types sitting in memory that I just don't need (40+ languages).

Alas, I tried using it for matching URIs and was dissatisfied. I can understand that it doesn't recognize unusual URI types, such as doi or svn, but it doesn't recognize https or ftps. Yuck.

EOL (v0.0.2)

No mention of existing modules with similar functionality: Text::FixEOL, PerlIO::eol, Whitespace.

As usual, namespace nit: toplevel EOL is a bad name. Why not in the Text::* namespace?

DateTime-Natural-Parse (0.04) ***

This is not well documented, which is an important issue since parsing is a difficult problem. Meaning is contextual.

If I say "this morning", what time does it give? Looking at the source, it assumes 8am. But what if I meant a different time?

If I say "this morning" at 1am, do I mean the morning of the day before, or the moorning which occurs later? Or do I mean the current time (which is still technically morning)?

How does it handle unknown words? If I say "this coming Friday" or vague phrases like "in a couple of days"?

Can I specify holidays? If so, words like "sabbath", "Easter", "Eid", or "Thanksgiving" are dependent on the religion, region, or country of the user.

There are no comparisons with Date::Manip, which has some similar functionality. (My own experience using Date::Manip in an application to give users flexibility in how they entered dates and times is that they had so many bizarre ways of specifying the time that it turned out to be easier for the developers and users to require a standard input format, which was eventually replaced with a drop-down menu for choosing the date and time.)

The idea behind it is nifty (in a toy kind of way), but it's strewn with pitfalls. From past experience with somehting similar, I'd not use this in a production environment.

And the obligatory namespace nitpick: should be in the Lingua::EN namespace, or at least indicate that it's English-language-specific.

W3C-LinkChecker (4.3) *****

It works well, and even makes recommendations about updating links which point to referring websites. Only some minor nitpicking:

* For links to password-protected pages, it says "The link is not public. You'd better specify it." It's not clear from the documentation how one specifies for the robot that the site is password protected.

* It doesn't install through the cpan shell, so must be manually downloaded and installed.

Math-MultiplicationTable (0.01) *

It generates a multiplication table, as a printable string.
No options to control layout or format, etc.

This has little use outside of an exercise from a How to Program 101 class. What is the point of uploading something like this to CPAN?

File-Copy-Reliable (0.30)

It just compares the sizes of the source and destination files. It's better than no checks, but I'd hardly call that reliable.

Why not options to add various degrees of reliability checks, such as comparing the source and destination files, or comparing checksums of the files?

One of the stated uses is for copying over networks, where even minimal checks are needed. The flaw may be in using File::Copy as a base, rather than something else which does validation checks for each block copied, or that is network aware. How does this compare to using scp or rsync?

Text-Bastardize (0.08)

Various methods which munge text strings, things like rot13, pig latin, or "censoring" words by changing vowels to asterisks. Mostly novelty use, so it should be in the Acme namespace.

String-CRC32 (1.4) ****

It's simple (just provides a crc32 function), and seems to do what the docs say.

No bells and whistles like OO interfaces so that one can initialize it, throw arbitrary chunks of data into it, and finalise it when ready.
But that's not needed for most cases.

I do wish the package style would be updated to modern standards, but the module is still relatively up-to-date and can still be installed using the cpan tool.

Module-Inspector (0.03) ***

This version appears fairly well documented, except that the TODO says "implement most of the functionality". What functionality is missing?

Having written code which examines distributions to extract information before, I understand the need for this module. There's not many tests on it, but I hope that it turns out to be portable (e.g. runs on Windows , Macs and various Nix flavors). I look forward to making use of it when (if?) I take up some old CPAN-related projects again.

WWW-AA (0.01)

It's got unedited stub documentation created by h2xs, so it looks like a namespace grab. But there's some code that does some kind of encoding/decoding, along with one-line comments in Japanese (I'm guessing Japanese by the author's name). What's it for? What does it have to do with the web?

Crypt-Lite (0.82.06) *

This package worthless. The author falsely claims that multiple encryption increases security: that's snake oil.

It seems to be throwing in data generated by rand(). Not very secure at all.

Installation of other crypto packages with complex dependencies is a false reason for promoting this package: it's eas yto install many of them, even on a Windows machine with no compiler.

Whether other packages have more complicated interfaces is no reason to provide a simple interface with a junk algorithm.

TeX-Encode (0.6) ***

It's fairly easy to use, but the job it does it less than satisfactory when decoding TeX.

Some of the translations are wrong: {\L} is translated to "L" instead of L-stroke ("Ł").

It cannot distinguish between TeX markup, such as \emph{emphasized text} and unrecognized character codes, but it does remove the initial backslash. If I have to separately parse the text to handle other markup, I may as well implement a character decoder there too.

So this module is of little use for decoding.

Tk (804.027) **

This review is based on using Tk for a project two years ago.

The reason the project used Tk over Wx is that it was the only thing that ran on our Windows machines. (We wanted to use something that was OS-independent, but most clients had Windows.)

The calling style is very un-Perlish. It's not even C-ish. It's Tcl-ish. Preceding argument names with dashes is a serious annoyance, especially when you are dynamically generating widgets from code templates. It's a struggle to keep code form looking like unreadable spaghetti code.

Generating widgets form code templates (that is, subroutines which generate more subroutines) was painful.

Argument names were not intuitive. The documentation was poor, and required consultation with the Mastering Perl/Tk book and a lot of searching on the Internet for examples. Some settings just never worked.

It took a lot of experimentation to learn how to use the different layout managers so that the windows were aesthetically pleasing. The code seemed kluge-fulled. Even then, the actual application looked like a no-frills X-windows application, rather than a native Windows (or Mac, or Gnome) application.

Text-BibTeX (0.36) ****

I've used this for a project to generate BibTeX entries from a list of publications. It seems to work quite well.

But it doesn't seem to do any escaping of characters (perhaps I need to RT*M a bit more?). I also needed to convert the author list from comma-separated string to "and" separated. Not a big deal, but this is probably a common task that a module with utility functions would be helpful.

I also wish there was a "Simple" interface for generating "regular" BibTeX entries based on a hash.

Still, it saved me from writing code to generate or parse BibTeX.

cwd (HASH(0x9fd52b0)) *

Very bad: there is already a "Cwd" module, which has been part of the core since Perl 5.000. The name "cwd" will cause problems on systems with case-insensitive file names.

Not so good either: no version number, and a default README file do not give me confidence in the module's quality.

It's not clear why this should be a pragma. Pragmas are for modules which alter Perl's functionality (even if in a limited scope). All this does is allow one to temporarily change the directory that code is running in. How this is a (better) alternatrive to using File::pushd or Sys::pushd (let alone Cwd or File::chdir)?

Bundle-PBib (2.08.01)

This is a Bundle distribution which contains several modules! Bundles are not supposed to contain modules, but are meta-packages.

The Bundle namespace is ignored by most automated testing software. CPAN and CPANPLUS shells have problems with this package because of that.

Acme-MetaSyntactic (0.74) ****

This is useful for generating a sequence of nonsense variables like foo, bar, baz etc.

But now it's overkill--even for an Acme module. The package has dozens of "themes" which probably belong in separate plugin packages.

Prima (1.20)

Minor nitpicking question: why does this package have a separate INI-file module, when there are already several others on CPAN?

Snail-CSV (0.07)

This package doesn't compare itself with other CSV packages such as Class::CSV, Tie::Handle::CSV, or DBD::CSV (among others). What does it do that others do not?

The name "Snail" in it does not imply confidence in its efficiency.

File-Path-Expand (1.02)

I hate these "this module is misnamed" reviews, but alas...
it's a wrapper for User::pwent that checks for $HOME beforehand. I'm not sure how portable it is: it probably should make use of File::HomeDir instead.

(I would point out that Cwd's "abs_path" does the same thing, but it's buggy: works for "~user" but not "~".)

Module-Signature (0.53) **

After some ongoing bad experiences with this module, I really needed to edit my review and lower the rating.

This *should* be an important tool for verifying that distributions aren't tampered with. But the security value is limited, especially in an automated or partially-automated (CPANPLUS) environment.

It only checks that a signature is good, but does nothing to enforce that the key belongs to the author associated with the module, nor is there an option for it to enfore that the key used to sign the distribution is in a web of trust.

It has problems with end-of-line conventions when files are shared between Windows and Unix. So signatures sometimes fail for text files when checked on platforms with different end-of-line conventions. So builds fail...

It also inherits problems from GnuPG. GnuPG is unable to request subkeys from keyservers. But that's ok since some keyservers mangle subkeys anyway. But Module::Signature will let you sign a module with a subkey. Ooops.

So in order for my modules to be useful to a (important) segment of users, then I have to disable module signatures in the distribution.

It's rather sad, but a lot of work has been put into an illusion of security.

Spy (0.00_02)

Minimal documentation for the B:: module, and none for the Spy::* modules. What does it do? How does one use it?

Attribute-Handlers (0.78) ****

This is an easy-to-use interface for defining custom attributes. But there are several annoyances:

The documentation is not as clear as it could be. For instance, it's not obvious how to "export" attributes so that they can be used in another package. I've had to look at code in CPAN to see that the handler should be called "UNIVERSAL::Name" instead of "Name". I hate putting things in the universal namespace, and indeed that leads to conflicts. (Attribute::Handlers and Class::Std are incompatible, for instance...)

The documentation does not make it clear that the distinction between running the handler when the attribute is defined, versus a handler that mediates access to the object (as with a tied interface). Parts of the documentation imply the latter, others imply the former.

If I create an attribute name in all lowercase, I get a warning about how it might become a future reserved name in Perl. Ok, but I don't care and want to turn that warning off, specifically. How?

Variable-Strongly-Typed (v1.1.0) ***

Unlike Attribute::Types, you can assign types to subroutines.

But the name is inappropriate: it checks the type of the return value of the subroutine, rather than wanted value. "Strongly typed" implies compile-time checks and a degree of type safety, so it would disallow things like

$len = @list;

I tried to show a nice counterexample,

sub foo :TYPE('ARRAY') {

return (1..10);


$bar = foo();

Well, this doesn't work, but not for the reason you would expect. Type 'ARRAY' is an array reference, not an array. It's documented, but it's not intuitive.

It would be nice to differentiate between arrays/lists and references to them.

File-HomeDir (0.57) *****

I really like the idea of this module (a platform-independent means of identifying the home directory), and don't understand why this functionality wasn't added to something like File::Spec.

This new version supposedly fixes the Windows bugs from v0.06, so there should be no reason for people to roll their own home directory code. (I no longer use Windows, so I cannot test the quirks in this.)

I particularly like how the newer version adds support for "my_documents" type folders. I hope to see future versions interoperate with File::Temp and File::Basedir.

DBD-CSV (0.22) ****

I've only needed this for very simple queries on single tables, but it works quite well, despite the limitations of CSV (no types specified for fields).

It's particularly useful for adapting to any delimited text file.

My only gripe is that it doesn't automatically detect the end-of-line conventions. It's particularly messy when you have a CSV file shared by people using different operating systems.

Rcs (1.05) ****

I was looking for something to extract the latest version of a file from the "rcsfiles" inside a local CVS repository.

The interface is very simple, though RCS command options are passed directly to the methods, rather than using perlish options which do the magic for you.

The package works and does what I need, quite simply and quickly.

Rcs-Parser (0.02) *

All I need is a simple utility to extract the latest version of a file from an RCS ",v" file.

This module doesn't seem to work. But I cannot tell if it's due to poor documentation or a bug in the system.

There's very little example code. What's there is wrong (it says to use "new RCS" instead of "new Rcs::Parser"). It seems to parse files created by "rcs", but runs into errors related to log entries and so cannot extract a version.

It chokes on files created by CVS.

The documentation does warn that it's alpha quality, but it's nearly useless.

Class-Date-ISO (0.01) ***

It adds an "iso" method to Class::Date which returns an ISO-style string.

But that ability is already in Class::Date. On just needs to set the desired format and use the string method.

I'm rather iffy on the means it uses to add the method to Clas::Date.Rather than inherit the class it specifies a new Class::Date package with the added method. (Admittedly I've never seen this style of adding a method to a class, but it seems dodgy to me.)

Class-Entity (0.1)

No MANIFEST, no README. A typo in the POD says it's documentation for "Clas::Entity".

Why does the name Class::Entity have to do with "Object interface for relational databases"?

DBIx-Class-Loader-ADO (0.02)

tar files come in two flavors: GNUTAR and POSIX. WinZip only supports the former. Lack of WinZip support is no reason to criticize the package.

DateTime (0.34) ***

This module does more than you'll ever need for Date-time calculations and handling. I'd call it the de facto standard, were it not for the load time. Adding a "use DateTime" statement to a script adds a quarter-second to the start-up time on my machine (admittedly it's an old machine, but it's hardly a klunker). So I'm hesitant to use it for simple date-time manipulations.

I'm also curious why there's no constructor to take the stringified date/time and reinstantiate it as a DateTime object. (Or if there is, it's not documented.) If I have to use an additional module or write my own parser, then it's less useful. Date::Calc does what I need and loads significantly faster.

File-BaseDir (0.02) *****

I've not given it a thorough evaluation, but it seems useful if you need the base directories. My only nitpick is that the module should have Freedesktop in the name, since it's not useful for anything else.

Sys-Filesystem (1.18) **

The documentation is wrong: it gives an error when you give the "regular" option to the filesystems() method.

The options are disjunctive instead of conjunctive: I want a list of mounted (and) regular filesystems, but I get a list of filesystems that are either mounted or regular. Once I have a list of filesystems, there's no way to query each object in the list to see if it's mounted or regular.

So it's of limited usage.

List-MoreUtils (0.18) ****

These are useful utilities, but I have a problem with the names of some of the functions.

"true" and "false" return counts of the number of true or false return values in code blocks operating on the lists. But reading code which uses them is confusing. One would expect them to return truth values, not numbers. A more intuitive name would be "count". (And one only needs a count-true method; false is easy to implement from that.)

One could nitpick about other function names, but they're not as critical.

Text-Trim (1.00) ****

It's one of those things that you constantly find yourself writing, so why not put it in a module. I might still insist that since it's only a regex, it's not worth it as a module (especially a non-core module). But it supports void context and trimming entire lists. It also can differentiate between leading and trailing whitespace.

Regexp::Common has a whitespace module, but cannot differentiate leading and trailing whitespace.

Clone (0.18) ***

This module is almost great. I've implemented some classes and needed to add "cloning" ability. Rather than write complicated recursive cloning functions (which I started doing....) I found Clone. It was as simple as adding

use Clone 'clone'

to the code to add a clone method to the class, and it seems to work with no problems.

But minus one star because it doesn't make use of any serialization hooks like Storable does. So for certain kinds of objects, clone just doesn't work. Minus another star because the documentation does not reflect this, aside from a recommendation to use Storable's dclone for slower but more reliable cloning.

Since Storable is a core module now, I'd just assume use that instead.

Data-HexDump (0.02) ****

I needed a quick and dirty way to show a hexdump of some binary data in Perl. This module exported a HexDump function that did just what was expected: return a string of lines of hexidecimal numbers and ASCII characters from the data. Which allowed me to quickly verify whether some software was working or not.

Only downside is that the tests gave a lot of warnings about pack formats.

podlators (2.0.3) *****

I was using Pod::PlainText to convert Pod to text. Alas, it didn't support the head3 and head4 tags. Pod::Text does. It's also a drop-in replacement (in part because Pod::PlainText was branched off from it), although it's since been updated. I'm happy with it.

Config-INI-Simple (0.01)

Wow! Yet another INI file module, only seven days after Config::Mini released to CPAN, and yet no mention of that or of Config::IniFile, Config::Tiny, and Config::IniHash.

Ok, but *why* use this module as opposed to other modules? What does this module provide that others do not?

Config-Mini (0.01)

Yet another module to handle INI files.

Ok, so maybe 'there is more than one way to do it' but the documentation should at least compare it with Config::IniFile, Config::Tiny, and Config::IniHash.

WWW-Mechanize (1.16)

This looks like an excellent package, but I've never been able to get a version which passed the tests on the Windows or Linux boxes I've used. So I'll have to disagree with the comments that this should be a replacement for LWP::UserAgent. The fact that this package often (but not always) fails tests on certain platforms makes me reticent to require it for an application.

Module-Build (0.2611) ****

After using it for years, I'm still very happy with Module::Build.

It is way-better than MakeMaker. It's easier to use, allows one to specify more complex requirements and recommendations than MakeMaker allows, but it has backwards compatability so it can generate Makefile.PL as well as Build.PL.

I strongly recommend using this and as a replacement for MakeMaker.

One important and subtle hitch: it does not handle auto-splitting automatically, and the docs indicate that the autosplitting interface may change. So if you've installed an earlier version of your module (using older Makefile), it will pass tests because autoloading methods are already available, but it will fail CPAN testers.

Another nit (and the reason I've updated my review): one does need to read the docs section "Alternatives to PREFIX" before complaining about it: <;

UNIVERSAL-clone (0.01) *

I'll chime in as well, but for different reasons: Clone (and Storable) cannot handle all objects, particularly onjects which do some low-level memory allocation in C.

It's not clear for certain types of objects what a clone is: should a clone have the exact internal data structure (an issue for non-deterministic algorithms), should the response times to queries be the same, or should it merely have the same data?

Bad things will happen if you rely on this to actually clone something.

Term-ReadPasswd (0.01)

I hate to give a module a "lousy namespace" review, but...

1. There is a Term::ReadPassword module already, so a Term::ReadPasswd module is confusing.

2. It's a Win32-specific module. So it should be called something like Win32::Term::ReadPassword, or Term::ReadPassword::Win32.

That said, despite the tests of Term::Readpassword failing in reports on Win32 machines, I recall getting it to work on Win32 when I used windows. I'm not 100% sure of this and no longer use Windows, but I'm skeptical of the need for a separate module just for Windows. I am sure that there already are modules which allow one to read from the console without echoing the keystrokes, even if it isn't Term::ReadPassword.

Date-Holidays (0.05)

I think the idea behind a Date::Holidays interface is flawed:

1. Wouldn't it be better to have a wrapper that reads arbitrary iCal files (which could have anything from holidays to events for specific institutions)? There are already many published calendars which are used by calendar applications ranging from Mozilla Calendar, Mac iCalendar, KOrganizer, etc. Better to have the module use that information (which might already be available on a machine) than duplicate (and inaccurate) information?

2. Why are holidays just delineated by countries? Don't various states and provinces have their own local holidays? Don't some localities (e.g. Scottish councils) have their own holidays? Don't some institutions (e.g. schools) have their own holidays that that they honor? And what about religious holidays?

3. Differentiate holidays from noteworthy events. Daylight savings time is a noteworthy national event, but is hardly a holiday. If one boths to put this information in a module usable by a computer, then there should be meta-information about this event that the computer can use (e.g. to know whether to expect more or less activity on the network).

Algorithm-Step (0.02) **

There seems to be no documentation in the module. Instead it's included in a separate script. So I'm not sure what sort of new thing this module actually does.

From the synopsis it appears to allow one to add "step" statements in various locations of an algorithm, so that one can watch the various steps. There are various debugging and log packages that can do the same, but can be "turned off" when not needed.

Steps are also numbered, but that may not be applicable to certain algorithms which do not have sequential steps.

It also gives some kind of statistic metric for each step, but does
not say what the number means.

And the information is simply printed. Better that it be logged to some kind of file for processing later. Perhaps another reason that the logging system like Log::Dispatch or various debugging and benchmarking tools would make a better base for this.

SuperLog (HASH(0x910289c)) *

Top-level namespace with no version and no POD. Very bad.

Logger (HASH(0x9103a00)) *

Top-level namespace with no version and no POD. Very bad.

Log (HASH(0xa3ae960)) *

Top-level namespace with no version and no POD. Very bad.

Data-PowerSet (0.01)

No rating, but just a note that there already exists a List::PowerSet module. How does this differ?

Perl-Review (0.04)

This sounds like an excellent module, but I have a nitpick with the namespace: it sounds like it has something to do with the managzine The Perl Review.

Perhaps it should be called Devel::Review?

Bundle-Ovid (1.01) ***

I'm not sure that a Bundle module that lists personal preferences of what a fresh installation of Perl should have belongs on CPAN. Frankly it's of little use to anyone but Ovid.

It makes little sense for me or anyone else to request changes since those reflect our preferences to what should be installed, not Ovid's.

It makes little sense for me (or I think anything else) to have out own Bundle::CPANID module since what extra modules are installed depends on the machine and what it's used for.

Log-Delta (0.03) **

This module inserts fine-resolution (Time::HiRes) timestamps into log messages, but otherwise doesn't provide the capability of other logging packages for log levels or multiple destinations, such as Log::Dispatch.

Indeed, it's easy to do the same thing with Log::Dispatch by using a callback.

Also: The PREREQS in he Makefile.PL aren't properly set. -1 star.

GMail-Checker (1.04)

Since GMail gives POP access, I'm not sure if this module is needed.

Mail-Webmail-Gmail (1.04)

Since GMail gives POP access, I'm not sure if this module is needed.

WWW-Scraper-Gmail (0.09)

Since GMail gives POP access, I'm not sure if this module is needed.

WWW-GMail (0.06)

Since GMail gives POP access, I'm not sure if this module is needed.

CaptureLog (0.03) *

I can't tell what this does. There seems to be only the .pm file in the distro, with no ChangeLog, README, etc. The documentation is garbled from bad POD formatting, and perhaps an unintentional global search/replace.

The module is named Log::SimpleLog::CaptureLog, but the distro is named CaptureLog.

There's no Makefile.PL or Build.PL, or tests either!

File-Slurp (9999.09) *

It just doesn't work all of the time. I can slurp one file, but then the second file it claims doesn't exist or it is unable to read anything from it.

I don't have the time to diagnose why it doesn't work. It was faster to write my own few lines which were adequate for what I needed.

HTML-Perlinfo (1.00) **

It's a lot of work just to output the Perl Config{}, environment, and server information to a web page. (There are several modules it uses for this.) One just doesn't need a module for this.

The question is, why?

The only use I can think of for this module is when one is given access to a web server that can run CGI scripts and needs to determine some information about the server and Perl installation. But that requires this module to be installed... if you can get the SysAdmin to install this module and its prerequisites, then why can't she answer your questions about the server? (And if she won't answer your questions adequately enough, why would she bother installing this module for you?)

Devel-Messenger (0.01) ***

This does not do anything more than Log::Dispatch, and if anything is less general in that it's intended for adding debugging messages rather than logging events into various places.

Finance-Currency-Convert-Yahoo (0.045) ***

It works well enough for my purposes, although it does not use a very efficient method of obtaining the information. (It parses an HTML page rather than downloadinhg the CSV.)

One problem is that it does not list the prerequisite modules in the Makefile.PL or META.yml.

App-HWD (0.06)

An abstract like "The great new App::HWD!" tells me nothing about what the module does.

It's bad enough when the first release on CPAN has a description like that. But several versions later?

Win32-File-Summary (1.00) **

Why does this module include Archive::Tar and IO::Zlib rather than list them as prereqs? The documentation for the included modues seems to be missing the copyright messages as well... are these the same as the CPAN Archive::Tar or a modified version?

The documentation for Win32::File::Summary is poorly layed out, it seems as if the author does not understand that POD parsers do the work of indenting and wrapping paragraphs etc.

Toolkit (0.0.2) ***

Toolkit lets you save typing or cut/paste by saying "use Toolkit" instead of "use strict; use warnings; use Acme::Whatever" and whatever other favorite modules you like to use all of the time.

It's a really neat idea. It is also a really bad idea.

It saves keystrokes. But the script or module ceases to be portable to another machine (let alone another OS), and the code is less self-documenting as to what modules it uses.

There's no tool to modify a script or module to insert the used modules in place of "use Toolkit", should one desire to see what's being used.

However, I can see cases where this would be useful: if someone has a large stock of standard modules to always be used.

I think it would be better to have some kind of "profile" configuration file that lists modules used (using "use", "no" or "require"). One could dump the module, or updated versions of Module::Build or ExtUtils::MakeMaker could include the profile file with a distribution, etc.

Carp-Indeed (0.01) **

This is meant to be used in the command line:

perl -MCarp::Indeed

but then one can use

perl -MCarp::verbose

for largely the same effect (the latter being part of the Core, however).

It redefines die and warn functions and forces their export but doesn't override the signal handlers, so many errors and warnings won't be caught by this. (The docs say it does muss around with the signal handlers, but it doesn't.) So it's only useful when a program calls die/warn/croak/carp.

The documentation has various rants about the meanings of words like "carp", "confess", "cluck", etc. (I suspect the author misunderstands the humor in that naming scheme) and some things about Acme::JavaTrace that make little sense.

Algorithm-Diff (1.1901) *

I'm trying to do a diff of two text files with about 40,000 lines each.
GNU diffutils finds 115 chunks but Algorithm::Diff finds one great big mega chunk.

Filter-Include (1.5) ***

When I saw this module, I asked "why did somebody write a module that uses Filter::Simple, Module::Locate and Scalar::Util, all to achive what you can do with core Perl using a require or do statement?"

Filter::Include includes the text of the file before it is compiled. The require or do statements parse the file (and do so at runtime). So in theory there's nothing wrong with that, provided you know the difference. The documentation does not explain it.

Instead it links to a thread on the web site, which if one reads, it seems that the thread was started by a novice who seems not to have understood what he was doing.

The documentation needs to explain the difference between what the module does, and using require or do (and using them in BEGIN blocks for compile-time inclusion).

In the end, I'm not really sure there's a need for this module so much as the illusion of a need by users who don't realize there's a better way. (Yes, yes, there's more than one way to do it, but not all ways are worth doing.)

Archive-Zip (1.16) ****

I needed to create and extract zip files, and was able to do this relatively easily using this module.

The only downside is that I had to study the manual a bit. Thinking of the contents as "member" objects (rather than files) is a little off-putting but it didn't get in the way. Especially since some accessorts are for "files" rather than "members"--I don't understand the difference.

Lingua-EN-AddressParse (1.14) ***

Note: I am told by the author that the module has been completely rewritten, and many of the problems fixed. However, I am no longer working on a project that involved parsing addresses, so I cannot verify this.

Below are previous comments for for v1.11 (which was released in 2002). I do not know if they still apply.

One major problem is that (for US addresses, anyway) it doesn't work unless addresses are very simply formatted:

123 Maple Street, Anytown, ST 12345

Anything beyond that (apartment numbers, post boxes, squares and cross streets, etc.) and it returns nothing.

Often addresses don't fit a simple pattern. (If they all matched that pattern, I wouldn't care about finding a module...)

Worse: it uses Parse::RecDescent, so it takes a few seconds to parse a simple address.

If it worked for most addresses, I'd say the "interface" and "ease of use" were great. Alas...

One note: parsing addresses is a HARD problem.

if (0.0401) *****

This is great for conditional "use" lines. It makes code a whole lot more readable than eval'd requires and import calls.

Win32::Security::SID / Win32-Security (0.50) ****

I needed a module to process Windows SID (Security Identifier) tags and found it. This did what I needed, though there were some problems:

It doesn't automatically call the ConvertStringSidToSid function like it claims it does (or the call is broken) when converting Sid to Name.

It also doesn't seem to export functions, so I had to use Win32::Security::SID::ConvertSidToName.

Those complaints aside, I'm happy I was able to do what I needed without resorting to non-CPAN modules like Win32::AdminMisc, Win32::UserAdmin, Win32::LanMan etc.

Text-Toalpha (0.01) *

The documentation does not explain at all what this module is for. It even warns "The permutation of characters to letters is not very well permutated," whatever that means.

The source code makes no sense at all as to what it's doing. It *seems* to be converting arbitrary characters to letter sequences and back, but the code doesn't look right. It uses a list and hash with some ord/chr conversions. (Why not use pack/unpack?)

Does anything use this code format?

Also, the default h2xs README is there. Not helpful.

File-Defrag (0.03) ***

The lack of any documentation for something as low-level and critical makes me not want to use this.

From a quick look at the XS source code it looks like it's Linux-only. If so, Linux::Defrag would be a better name.

All the interesting code is in the bin/defrag script: why aren't they in the module instead? It would be useful to have a module with a single defrag_file() function for instance.

The defrag_files() function to defrag all files uses a homegrown directory traversing scheme instead of File::Find.

I would expect a good defragmentation scheme would do a bit of analysis to see which files needed defragmenting (based on how fragmented files were, how often they are accessed or how critical they are, etc.). This version doesn't seem to do any of that.

Pod::PlainText / Pod-Parser (1.30) ****

It was incredibly easy to subclass this to create a custom PlainText parser with special commands/behaviors that I wanted, though I did need to deviate from recommended methods to subclass in order to get it to do what I needed. (I'm not sure if it's simply due to an omission in the documentation or not, though.)

Sub-Usage (0.03) ****

Providing usage error messages for subroutine calls (in much the same way a command-line program will when it gets back options) is a really neat idea, though the usefulness of this module is probably mooted by something like Params::Validate.

Test-Prereq (1.027) ***

This could be a great quality-control tool for module authors, although it is a bit slow in running its tests.

One complaint I have is that I'm not able to get the Build.PL checking tool to work properly, based on the examples. But that's a minor issue since I have the Build generate the Makefile.PL anyway.

Another is (on Windows anyway) is that it chokes on some modules and blocks on input from STDIN. This is a serious-enough bug that I've stopped using it.

Perl-MinimumVersion (0.01) ****

I've not tried this yet, so can't vouch for how well it works. But I really really really like the idea behind it!

Log-Log4perl (0.51) ****

This is an excellent package, BUT... it's a lot of work to set up the configuration for it. There's a fair bit of documentation to read to figure it out.

For a system of applications which use shared configuration information, this is worth using because a sysadmin can update logging information without touching source code--one can control what subsystems at a set level of granularity are logged (and to where).

But for most cases, I think using a simpler package such as Log::Dispatch will suffice. (It's the basis for Log::Log4perl anyway.) One can easily upgrade from Log::Dispatch to Log4perl if requirements become more complicated.

Log-Dispatch (2.10) *****

This is a great system. It's incredibly easy to use and even expand on.

File-DirWalk (0.1) **

How is this better than File::Find (which is a core module)? Maybe in that it gives various callbacks for entering/leaving a directory, but otherwise it has less features. There's no way to control whether to process files or subdirectories first, nor does it provide for filtering etc.

It uses global symbols in opendir(DIR, ...) instead of scoped variables, and does not use File::Spec for portable filename handling, so I'd be leary about using this in production code.

Test-Portability-Files (0.05) ****

I haven't compared what this does with the actual Perl portability recommendations, but this seems to be a worthwhile addition to an author's quality (or kwalitee?) assurance toolkit. It's very simple to use.

UPDATE: it's occurred to me that there are some (minor) issues that it doesn't test for. Suppose::You::Have::A::Long::Module::Name, well, each subdirectory is under 32-characters so it passes tests, maybe t/Suppose-You-Have-A-Long-Module-Name.t fails the test but it's easy to rename that to a short name, you you still have it all in a folder called Suppose-You-Have-A-Long-Module-Name-0.123 or whatever that the current version of Test::Portability::Files doesn't test for.

However, I'm not sure it really matters since the limit pertains to "MacOS Classic and old AmigaOS", which should be an option like MSDOS and removed from default tests.

I'm also not sure if it tests for the maximum pathname lengths of Windows 9x or maximum directory depth and length of ISO CD-ROM directories.

But these are easily fixable issues, so shouldn't detract using it.

Win32-Symlink (0.04) ****

This is great, but it does not give any warnings when one tries to create junctions to files rather than directories. It also does not document that this should not be done. But it lets you do this...

(I'm not familiar with the API to know if there's hooks to make symlinks to files for use in the future, though.)

TimeConvert (TimeConvert0.5) *

The functionality for converting between "unix seconds to years, days, hours and minutes" can be done with the gmtime function.

Worse, it returns a string "$years years, $days days, $hrs hours, $min minutes and $sec seconds." (from the source code, it's not documente how the result is formatted). So this is not much use.

Pod-Coverage (0.17) ****

It's great, but it's easy to misunderstand the interface and use it incorrectly so that it looks like a module passes Pod::Coverage tests when it doesn't.

Also, there are no hooks to handle inheritence. If a Foo isa('Bar'), then when Foo has methods which override those of Bar, Pod::Coverage doesn't recognize this. Sometimes that's expected behavior: maybe you should odcument exactly what's changed. But sometimes you document it differently, and do not want to list every updated method. It would be nice if there was an option to recognize when this occurs and ignore them.

pod-mode (0.3) ****

This works well in XEmacs. I'm quite happy to have something like this for editing POD.

Test-Expect (0.29) *****

I whipped up some tests of a Term::* module quickly with this. It's great!

If you've got any module which requires testing by verifying terminal input, use this. It's more foolproof than having a user type things in and is friendlier for cpan smoketesters.

My only nitpick is the "Expect" name (it should be called "Test::Term" instead), but understandably the name comes from the use of Expect and Expect::Simple.

Hoof (0.01) *

There's absolutely no documentation. Not even an abstract. I have no idea what it does. Why bother uploading it to CPAN if it doesn't even have stub documentation that says what it's for, who the author is (it's the only module under the author's id) and what the license is?!?!

SQL-Statement (1.10) ****

I've had to use SQL::Parser for some projects that involved analyzing select statements (from various database dialects) to determine the structure of database tables. It was relatively easy to use for my purposes (though it required a patch to handle aliases, which has since been incorporated into 1.10).

Most of the work involved analyzing the data structure returned by the structure() method, which required a little bit of experimentation to figure out what I needed (and was the only downside). The documentation is a lot of wade through.

A hash structure doesn't seem to be the most elegant way to access this information, but what is? It was enough for me to get what I needed done (and certainly saved me the work of writing a parser).

Math-XOR (0.02) *

This is just wrong. From the docs:

"This is the only method of encryption that (assuming the

randomness of the pattern used as an encryption key) truly

cannot be broken."

Well, if you had a "truly" random key the size of your file, then theoretically probably. (See the Snake Oil FAQ at <

All it does is xor two buffers together, and doesn't even check if they are different sizes (which will cause some nasty problems).

The namespace is inappropriate, but I wouldn't want to see the Crypt::* namespace polluted with this.

Time-Traveler (0.01) ***

I'm having a lot of trouble seeing what the use of this module is. Better examples would help explain that. The synopsis is a bad explanation of what it does.

If it's an implementation of lazy evaluation, then it seems to have more natural interface than Data::Lazy though with no ability to control whether evaluation is for reads versus writes.

If it's for a history, how does one rollback a value? (Note that there's Tie::History for this.)

Data-Search (0.03) **

This is an interesting idea, but the implementation leaves a lot to be desired.

There are no tests aside from compilation. So how does anyone know it even works?

The searching algorithm does not appear to be very efficient: when searching arrays it uses a foreach statement instead of grep or an efficient search algorithm!

It doesn't make use of other CPAN modules which might aid in walking data structures or efficient searching. I'm concerned about the use of recursion in walking data structures: for really big data structures this is a memory hog that can bring down a machine.

It doesn't handle coderefs!

It only allows one to search using Regexps. There's no option to use special code appropriate to objects inside the data structure or anything else that is not stringified.

The documentation isn't as clear: can it return the accessor keys, so that if I pass it some mess of hashes and arrays in $data that it will return something likie $data->{key1}->[5]->{key2}->{key3}?

What sort of applications is it used for? Perhaps the need to search is due to building an inefficient data structure to begin with? Or maybe one needs to do the searching as one is building the data structure?

Archive-TarGzip (0.03) ***

I fail to see what improvements this module provides over Archive::Tar.

Data_Translate (0.2) **

Is this module really necessary? It's a wrapper for unpack() calls. Worse, it has an object-oriented interface when function calls will do, so there's extra overhead that is not needed. Every conversion function is loaded into memory even if it's not used. (Though the functions seem too simple to justify the AutoLoader.)

Also: the translation to/from binary do not take endianness issues into account (sometimes one needs to explicitly use little-endian).

I would defend the idea of provided simple and commonly-used functions in a module just to save one from having to re-write the same few lines of code each time, but there should be _some_ extra functionality to justify this.

Test-Plan (0.02) ****

Everything about this that I've tried is great, except (a big except): it doesn't add any new functionality beyond what's available already. It just adds a better syntax.

Problem then is that one needs to require Test::Plan to build the module. Is it worthwhile for module users? I'm not sure.

Text-Greeking (0.11)

This module appears to do the same thing as Text::Lorem, with a very similar interface.

Weather-Com (0.4.1)

I'm neutral as to the quality of this. It seems to be quite an elaborate package for interacting with the Weather Channel's web services.

As for the namespace, it's awful. "Weather::Com" is just way too wrong.

Regexp-Assemble (0.09) *****

Rather that loop through an array of Regexps looking for a match, this module allows for one to combine them all into one Regexp. This makes code much cleaner and easier to maintain. It is an excellent module.

Note that I'm not sure how well optimized the combined Regexp is compared to iterating through a loop, but for my purposes this hasn't been a concern.

CPAN-Mini (0.36) *****

This is a great module for maintaining a "mini" CPAN mirror locally. It's also very easy to subclass so that you can customize its behavior to suit your needs.

The only noticeable downside is that it doesn't rebuilt the package-details file based on how you've filtered your copy, but this is minor and will probably be fixed in a later version.

CPANPLUS::Backend / CPANPLUS (0.051) ****

CPANPLUS::Backend does not make it easy to automate CPAN-related tasks (such as running smoke tests on new CPAN modules).

It's not well documented, and the interface is too limited. To get a minimum script running requires quite a bit of hacking and using undocumented or private (names beginning with underscores, "_") methods.

For instance, it's hard to dig into a distributions prerequisites in order to determine if there's something that you know doesn't work and have it bail out. Or maybe have it fall back onto a previous version if the latest version fails a test. (It shouldn't be so hard to delve into the inner-workings of the module with some well-placed callbacks. But maybe this is possible, but just not documented?)

In certain cases it cannot properly parse the path to the module, requests the wrong URL and just locks up unsure of what to do. (Possibly a Windows-issue with time outs?).

The tracking of sent test reports seems to have been eliminated, which improves usage from the CPAN Shell but puts the onus on smoke testers to track results.

My frustration has tempted me to just roll my own fetch/extract/run Makefile.PL/make test and send reports code myself, but I do realize what a complicated mess it really is to handle the disgusting underbelly of module installation (especially in a platform-independent manner).

So in a perverse way I am grateful for all the work on it. This is an enormous effort so I have high hopes that some day it will be improved.

Cache-Simple-TimedExpiry (0.22) ***

The module has a simple interface and is easy to use. It seems to work quite well.

Alas, the documentation is sloppily formatted with an uncommented minimal example (that's missing an important use statement).

It also has no tied interface (which would make it really easy to plug into some existing applications that I have), and for that matter has a poor OO interface: store, fetch and exists with no delete, clear, first_key or next_key methods. (There is a method to return all the keys, but it's not documented.)

It also prototypes the subroutines, which means that you have to use parenthesis in method calls. Yuck.

If it weren't for the interface, I'd give it 4 stars.

Comma (0.02) **

I'm all for coming up with new programming idioms, but I fail to see the use of this module. A tied hash is being used instead of a simple function, so there is a lot of object-oriented overhead behind the scenes that doesn't need to be there, especially when there is only one global instance of the comma object.

Looking at the source, locale-specific formatting is automatic. There's no option to customize it, so if you're in one locale but want to produce formats in another locale, then you're out of luck.

However, the name 'Comma' is inappropriate for locales that don't group digits with commas.

Time-Out (0.03) ****

This is a great idea: the module has an intuitive interface for implementing time-outs. And (unlike many other time-out/alarm modules on CPAN) it has tests!

The only downside is that it does not work for blocking I/O (at least not on Windows).

Note: this is a review of v0.01

Win32-Die (0.03) ****

This is a great idea: automatically detect when a module is launched via clicking on an icon in Explorer rather than from the command line, and halting to prevent the window closing when an error occurs.

Alas, it's not perfect. It cannot detect when a separate window is launched from within the command line.

It also does not trap Ctrl-Breaks.

Nor is there a way to customize the error message.

Even then, this is a must-have for Win32 Perl developers.

Regexp-Parser (0.10) ****

This appears to work very well, and has some handy interfaces for iterating over nodes.

However, documentation of the specific node-types could use some improvement.

Win32-Process-Info (1.004) *****

This works really well. My only complaint is that it seems to be a little slow in querying the process list.

Win32-Console-ANSI (0.07) *****

All one needs to do is add a 'use Win32::Console::ANSI' to the program and it works like a charm. It's great!

Regexp-Constant (1.22) ***

How is this an improvement over Regexp::Common?

Test-TempDatabase (0.02) *

This module doesn't provide options to specify what database one wants: only Postgres is used, so if one doesn't have DBD::Pg, one cannot use it.

What does creating a temporary database have to do with Testing? It should be called something like DB::Temp.

The abstract/author sections of the Makefile.PL are not updated, and the requirement for DBD::Pg is not specified in the Makefile.PL. Nor has Changes been updated.

Digest-Crc32 (0.01) ***

What is the point of this module?

There is already a Digest::CRC module (which it refers to in the SEE ALSO section) but it says nothing about how or why this module is more appropriate than that or the several other CRC modules.

It has a negligable test (only tests the string "foo") and doesn't attempt to account for portential endianess or sign issues.

File-Info (1.02) **

This is a rather inappropriately named module, as it deals with caching file information rather than retrieving it. It would be better named something like File::Info::Cache

It also supports a uselessly limited number of file types (Unknown, JPEG, or PAR).

It stores a line count but not other 'wc' details like word count, longest line, etc.

It seems to have the ability to add these features, but examples are not provided. Some sections of the documentation are blank.

The Makefile.PL uses a non-standard home made scheme that is not usable by CPANPLUS (or presumably CPAN).

File-Munger (0.02) **

I'm having a hard time seeing much use for this module, except as an object-oriented (and possibly platform-independent?) means of getting file information. In which case, the name is completely deceiving: it does no munging (manipulation) whatsoever of the file or attributes. (Admittedly File::Info etc. is already taken, but "Munger" is the wrong name.)

The current version (0.02) does not provide any features not already available in the Perl core. Useful things like file type, information relevant to the file type (e.g. image properties or character sets for text files or version information) etc. is not available, nor is platform-independent file information (such as pathnames).

The documentation does say more features would be added. It would be nice to know what the "master plan" of the module is.

SOAP-Lite-0.60a (SOAP-Lite-0.60a) ****

The documentation is ok... there's a lot to wade through, but there's enough to figure out what you need to do. There are examples buried in a lot of documentation. You may need to experiment a bit, but it's easy to get the hang of.

It's pretty easy to use, and the interface is good (not excellent, just good). (I'm told it doesn't support all of SOAP's features, but it's handled what I've needed.)

The main limitations are in the SOAP protocol itself. There's so much overhead in bandwidth and processing (most of the data is just XML markup that isn't needed) that you're better off using something else. (Not a slight on the module, but on the protocol.)

Business-ISBN (1.80) *****

I used an older version. For my purposes (validating ISBN numbers before submitting them to a lookup service), it worked.

Scalar-List-Utils (1.14) ****

This module has a lot of handy functions that give one access to low-level information without resorting to XS.

Clone::Any / Clone-Any (1.01) ***

It's easy to use, flexible, bundle of joy, etc. etc. and I would give it five stars, but....

If I just used Clone, it would work on most platforms (seems to have passed 26+ tests with no failures) and has no pre-reqs.

But if I use Clone::Any, it failed tests on at least one platform (this may be the specific machine it was tested on and not the module's fault, though) and it requires Devel::UseAnyFunc and a separate module capable of cloning.

So my choice is to specify using Clone which requires just installing Clone, or I could use Clone::Any, which requires installing Devel::UseAnyFunc and another module for cloning (such as Clone, though Storable is now a core module).

It seems like a great idea to just have the module look for whatever cloning routine is available on the system and use it transparently, but it is more work than just installing Clone. (If it were part of the core, that would be something else, but then again, one could just as well speculate if Clone were part of the core...)

One other potential problem: if I use Clone::Any instead of Clone, Storable, etc., then I risk that code doesn't work consistently across systems because of bugs in one cloning module on some platforms that is not in the other cloning module. If I at least use a specific cloning module, then I've eliminated some potential problems.

Class-Meta (0.44) *****

I really like this module. It took be less than 15 minutes to convert a module from a different automation scheme to this one.

The interface is very simple to use, and in my opinion, self-documenting. I can look at the code that creates the class and know what kind of data each accessor is, whether it is required, etc.

Other class automation modules were too simple. I needed some minimal data validation in the constructors and didn't want to go through making a dummy class with inheritence.

There are some minor features that it doesn't have, which I suspect some of the more sophisticated class automation modules do have. But again, this suited my needs. (And portability on Windoze, OS/X, Linux, BSD, etc. is one of them, which the more complex tools don't necessarily have.)

Class::Accessor::Fast / Class-Accessor (0.19) ****

It does the trick and saves a lot of repetative typing to implement no-frills classes.

One downside: there is very little error checking, so if you mistype the name of an accessor when you are constructing it using the new( { accessor => value } ) style, then it will miss it and cause some unexpected problems in your code.

If you need more robust features, this might not be for you.

URI (1.31) *****

This is very good for basic URL manipulation, especially to resolve weirdness between relative and absolute URLs.

HTML::LinkExtor / HTML-Parser (3.36) ****

I needed to download images from a web page, and used HTML::LinkExtor (part of HTML-Parser) to extract the image src links (based on an example on the module POD!).

It took me more time to download the images (lots of them on the page) then to write the code!

(A couple of things aren't clear in the documentation, such as whether the attribute hash for the callback is case-sensitive, or if only link attributes are extracted; fortunately for my immediate needs this was not an issue, but it should be explicitly documented.)

Module::Load / Module-Load (0.10) *****

I was unable to dynamically load modules for test scripts, so I tried this module and it fixed the problem. It's incredibly easy to use.

TkCarp (1.2) ***

One would expect by default that error messages instantly show up as message boxes, but they don't. One has to specify this. One also has to specify that they show up when they happen, instead of when the program ends.

Options are configured by specifying keywords in the use line rather than a hash with attributes, and manually asking for carp and croak since the default behavior isn't what one would expect.

croak does not seem to end the program, but causes it to partially lock up (though some events work and one can manually close it).

The options are nice, but the default behavior is not what the average developer would expect without reading the documentation.

Return-Value (1.1) *****

This is a really good module (4.5 stars) for adding diagnostic information to subroutine return values while still returning true/false booleans (using overloading).

It's easy to take existing code and add the use of this module to it.

The documentation is a little lacking in terms of functional calling style, so one needs to look at the synopsis and extrapolate.

The name Return::Value doesn't seem appropriate though.

RTF-Writer (1.11) ****

I like this module. I like it even better than the RTF::Generator module which I wrote (which *cough* doesn't work well in current versions of Perl and is an incomplete implementation anyway).

The interface is clean and simple to work with. I was able to produce an RTF very quickly.

The only downside is that you need to know the RTF and work with the (sometimes nasty) RTF innards rather than an abstract document in general.

Text-Balanced (1.95) ****

This works great for extracting balanced strings, BUT....

Read the documentation closely, since it does some unexpected (not functional-programming-friendly) modification of arguments in scalar context.

Once I read the documentation and realized what was going on, I got it working as I needed it. It can be a very good alternative to Parse::RecDescent when you're concerned about balanced parenthesis, quotes, brackets, etc. but otherwise simple grammars.

Class-DBI (0.96) ****

It took me a while before getting around to trying Class::DBI.

I really like it a lot more now, but it's not the easiest thing to use for a pre-existing database that may not have the best schema design in the world.

Sometimes simple database queries can be awkward, and it may take a while to debug the class design for joined tables.

It takes getting used to the iterator "pattern' of retriving database records. (I'm rather ambivalent about that style of programming.)

It's also awkward to specify dynamic connection parameters, but it can be done with some expiermentation. It's just not well documented.

Note: my review is for 0.95, because i cannot get 0.96 working on my platform. and the rating system will not let me specify an earlier version.

Params-Validate (0.74) *****

This is a great module for validating named or unamed subroutine and method parameters. It's easy to use, and seems to work without any problems.

My only "complaint" (read: wishlist item) is that there's no way to have both unnamed and named calling styles.

Test-Warn (0.08) ****

The interface is a little awkward, but it works well and allows you to test warnings.

Parse-CPAN-Packages (2.21) ****

This module allows one to easily parse the 02packages.details.txt.gz file for CPAN archives.

The major downside is that it has to initialize itself completely, which can take a while even on a fast machine (and will probably take longer as CPAN grows).

A couple of features such as determining what distribution a module is in required reading the source code since the documentation consists only of a synopsis, which leaves out a few things.

File-Temp (0.14) *****

This module seems to do what it claims: create temporary directories and files and clean them up when the program is done, without having to do any book-keeping.

It's very easy to use.

Win32-TieRegistry (0.24) ****

This allows for very easy access to the Windows registry through hash keys. It's incredibly easy to use, although I've not been able to set defaults in the 'use' line as the documentation describes.

XML-Parser-EasyTree (0.01) *****

This was really easy to use and allowed me to quickly parse a simple XML document.

Devel-Cover (0.45) ****

This is an excellent module! I've not only improved the test suite but used it to optimize software by identifying conditions that do not occur, or options that are not needed.

The documentation leaves a bit to be desired, though. It takes a bit of time and experimentation to figure out. (There are still a few things that I'll need to figure out...)

SVG-Graph (0.01) **

This looks like it has the potential to become an amazing distribution for generating SVG diagrams.

But it's barely documented (as if a utility was used to create POD by looking at the methods): there's a lot of empty templates listing methods, and that's it for most of the modules.

It's difficult to figure out, and I decided it would be easier to just find another module to do what I needed (which was to create a node diagram.... it appears that it at least has hooks to do this, if not the actual ability).

I have not tried it for plotting data.

That said, the documentation refers to it as pre-alpha. But it came out in November 2003.

UML-State (0.02) ****

This program is excellent for creating state diagrams, either through a text or XML file that describes the states and connections between them.

You need to define the state positions in rows, and then define how they are connected. The process is easy to figure out, and it's certainly faster to create an XML file than to twiddle with a drawing program.

Alas, this is almost-just-what-I-needed in that you cannot change the shape or size of the nodes (they are just equal-sized rectangles), and I need a general purpose tool for creating node diagrams.

Statistics-Descriptive (2.6) ****

This is a very easy-to-use module to show some basic statistics on some data. It's worth using rather than "rolling your own", even on a one-off script.

Attribute-Types (0.10) ****

From some very limited experiments, this is a very simple and effective way to control the types and values of variables in Perl.

This is a good way to enforce types or to catch errors in debugging. Though I'm unsure about using it in production code, especially since attributes are (were?) a moving target and subject to change.

A *major downside* is that assignment to variables is seriously slowed down, due to the fact that they become tied to a function that restricts their type. So don't use it for any time-sensitive code.

And of course it seems to increase a variable's size.

Text-Replace (0.07) *

Is it possible the author has something to do with this?

"On the internet, nobody knows you're a dog."

Devel-Size (0.58) ****

This is a very useful module for obtaining memory usage information of objects. It's quite surprising to see just how much memory some things really use!

An obvious downside is that it doesn't work for every type of object.

It would be nice to obtain additional information about memory usage in Perl (such as total used memory of a module, or available memory, etc).

Tk-Date (0.40) ****

I've been able to get it to do most of what I wanted, without having to write my own date/time input functions.

I can live without the features that it doesn't have (AM/PM time input is in the TODO list) or that I've yet to figure out.

Win32-TaskScheduler2.0.3 (Win32-TaskScheduler2.0.3) ***

My overall rating is 3 out of 5 because of ambivalence.

I had trouble compiling it due to some vague function calls, but eventually found a SourceForge page at that had a compiled version to download via ActiveState's PPM. The documentation did not mention this (it has a blank SEE ALSO section).

The Source Forge site refers to the Windows documentation, but that leaves something to be desired as well.

It follows the Windows interface style too closely. You use New() instead of new(), and have to manually call the End() destructor. There's no option to import constants, so you have to use Win32::TaskScheduler::CONSTANT or $obj->CONSTANT. I would rather the interface followed traditional Perl style and calling conventions.

However, I figured out how to get it to do what I needed within a few minutes. And it seems to work relatively well.

Tk-Wizard-Bases (1.06) ***

In some ways this is an excellent module. When running, it looks quite professional.

Alas, there are some issues: it is designed as a MainWindow (e.g. as a standalone application) and so is not easy to embed as a Toplevel window within an application.

Stylistically it looks like a Windows 95 or 2000 installation wizard, which is not appropriate for a wizard that occurs within an application and may bother or confuse some non-Windows people.

Tests are not automated, as it runs actual wizards that require human intervention. It also requires manually moving some image files into the perl directory for the tests to work.

The documentation leaves much to be desired. It's sparse and recommends one look at the test case files.

It makes some assumptions about how wizards should work that are restrictive. For instance, there is no way to have both "Finish" and "Next" buttons in cases where the user can end early.

Also: E-mails to the author have bounced back.

Sadly, this is a case where an otherwise excellent module has a lot of issues that make it too restrictive for my needs.

Data-Page (2.00) ***

Given a list of items, the number of items per page, and a page number, this module only manages where the starting item number is, and it gives you an array slice for that page.

Understandably, it doesn't manage how to view the pages since they can be implemented via Tk, HTML/CGI, console, etc.

However, more functions to handle paging would be good. Such as a goto function to go to a particular page (page n, previous page, next page, etc.).

Without such functions, you still need to keep track of the page number, and to recreate the object for each page. So it has a limited usefulness.

enum (1.016) *****

This is very useful, although I have not tested it beyond simple enumerated lists. It should be a core module.

One thing it can't do, but this is largely a Perl limitation:

use enum qw( FOO BAR );

my %MOO = (

FOO => 'Foo',

BAR => 'Bar',


Pod-POM (0.17) ****

This was surprisingly easy to use. I needed to do some specialized parsing of POD and convert to HTML, and it worked right out of the box.

It was easier to figure out than Pod::HTML in terms of interface and documentation.

One downside is that it has problems extracting POD from code. One needs to use a separate module to do this.

XML-Generator (0.98) *****

This module is very easy to use: it's similar to the kind of interface that I was looking for (and would have written had I not found it), which is basically to use AUTLOAD to use method names as the XML elements (similar to the way CGI does).

Cons: the pretty printing doesn't handle attributes well, and it's difficult to handle the namespace attributes (which to be honest I haven't figured out from the XML specs themselves).

Win32-Daemon-Simple-0.2.2 (Win32-Daemon-Simple-0.2.2) *

Various problems with this module that keep it from working out of the box: It requires various other modules but the Makefile.PL does not specify them. Then it uses a symbol $HKLM which is not defined, so it basically dies with a compilation error.

Carp-Assert (0.18) *****

Having assertions makes development and debugging much easier.

The only down sides are that it's not part of the standard Perl distribution, and (maybe I'm wrong about this) if a module uses it, can the script that uses that module override the use/no Carp::Assert setting.

Win32-SerialPort (0.19) ***

This module hasn't been updated since 1999. That's a serious issue.

The interface is messy and one needs to study the examples, but supposedly it's the same as Device::SerialPort.

A problem is that I need to write klugy code in a BEGIN block to test if I'm in Windows and use the Windows::SerialPort module instead of Device::SerialPort. Somebody should look to merging the two modules.
[Ok... I've since realized that Device::SerialPort is a mimic of the Win32 module, but still, there should be ONE module.]

However, it seems to do what I need it to.

Parse-Binary (0.06) *****

I needed a simple and dynamic way to create and parse binary data formats to communicate with a GPS device using a serial interface. I was about to roll my own when I stumbled across this module.

I've been using Parse::Binary::FixedFormat. It's simple and does the trick. And it makes my code much easier to maintain.

HTML-Template (2.6) ****

Note: this review applies to earlier versions of HTML::Template.

This is an excellent module. This one has made web application development much easier for me.

The only downside is with using simple loops with one value. It seems like a kluge to have to convert an array into a hash. It's also awkward to specify a "default" option for select lists. These are both common issues that I think deserve implementation in the module.

Spreadsheet-WriteExcel (0.42) ****

Overall it is a very good module, but it takes a lot of work to tweak if the formatting is complicated. It also requires figuring out arcane Excel speadsheet formatting codes, half experimentation and hacking and half searching through the documentation.

It would be nice to be able to generate the spreadsheet entirely in memory rather than a new file, though.

RTF-Generator (1.00) *

The documentation has not been written. But otherwise flexible interface when one figures out how to use it.

Rather worse: it does not work properly in current versions of Perl.

(Yes, I'm reviewing my own module as a test of the reviews.)