Reviews by Adam Kennedy


Adam (0.04) *****

The name alone makes this quite possibly the most awesome module of all time!

Text-Unidecode (0.04) *****

A little stale, but a work of brilliance nonetheless

Win32-Uptime (1.01) *****

This review is provided solely as a counter to an incorrect review of this module as a "squatter". It's nothing of the kind, it does actually implement what it says it implements, and seems to do it well.

Win32-MediaPlayer (0.3) *****

Very handy module.

I used it to write myself a neat little custom alarm clock, which plays nice relaxing wake up music gradually increasing in volume over half an hour.

And if that doesn't work, ramp the volume to maximum and crank out random techno or death metal.

More useful for sound, video appears in an uncontrollable window wherever the hell it wants to. And unfortunately, you can't load playlists.

But still a great module.

common-sense (2.0) **

Very interesting, efficient, and potentially something I'd use all the time.

But it's let down twice by the module name and the abstract ("Kittens?") which make it extremely hard to do things like request packaging from corporate IT departments without going through uncomfortable amounts of grilling.

So no common::sense for me, alas.

Religion-Islam-Quran (1.0) *****

This module appears to provide legitimate functionality on a correct and neutrally-sourced data source that just happens to come bundled with the module.

I add my endorsement.

Acme-CPANAuthors-AnyEvent (0.01) *

This is the most stupid module in the whole stupid series of stupid.

It's like someone took the =head1 AUTHORS section of the AnyEvent POD, doused it in stupid and set it on fire as a beacon of stupid, a benchmark against which all future stupid would be measured.

XML-Tiny-DOM (1.1) *****

A surprisingly elegant API for something that's just a tiny wrapper around a tiny parser.

Dackup (0.41) *****

This is simple to configure and install, and great for setting up manual backup schemes. Add cron and it's basically set and forget.

Two thumbs up.

JSON-CPAN-Meta (3.000) **

This module is based on the assumption that META.yml is YAML as described by the YAML specification.

This, unfortunately, is not the case. META.yml was created at a time when YAML was immature, and as a result it presents some problems in this regards.

The use of JSON in META.yml is likely to cause problems, and should be avoided wherever possible.

For more in depth discussion, see the following

Parse-Marpa (1.000000) *****

This review is intended to negate the silly premature one-star review and remove some of the stain it's left on this module.

mpp (8) **

While this is a great idea, currently the modules in this distribution are dumped right in the root, and stomp all root namespaces.

This extreme disregard to the CPAN namespace makes me extremely reluctant to use this, as I can't help but wonder what OTHER strange and destructive things it does.

Data-Dumper (2.121) ***

On the plus side, Data::Dumper is in the core, so it's always going to be available. However, I personally think this has lead to overuse when perhaps it isn't as useful as other things.

What do I mean?

1. Data::Dumper should probably not be used for caching or storing Perl variable/object trees on disk for machine-only use. Storable is far far faster, and more compact.

2. Data::Dumper should NEVER be used for anything security-sensitive, or when moving data across trust boundaries. Because it is code, it's trivial to inject denial-of-service or exploit code into the dump. Non-executing formats like Storable (with CODE execution disabled) or YAML (with CODE execution disabled) should be used instead.

3. Data::Dumper isn't really the easiest thing to read. The profusion of commas, the the fact that a blessed object's class will be at the END of the giant thousand line nesting complicate things a bit. Something like Devel::Dumpvar (which is a standalone implementation of the format used by the Perl debugger) seems to be more readable.

That said, Data::Dumper is still very useful. But I find the number of places that I need it is gradually being stripped away by more useful specific purpose modules.

My other minor nit is that, for a core module, it doesn't seem to work on 5.005 any more. So it's no longer updatable on older codebases stuck on old machines.

Config-JSON (1.3.0) ****

This module is a straight forward implementation of a config file object using JSON as the underlying storage mechanism and seems to be implemented competently, if a little cargo-cultish (uses when it doesn't really need to, and has use warnings in the Makefile.PL without making a 5.006 dependency declaration). However since my last review most of CPAN has moved to a minimum 5.006 dependency anyway, so these issues aren't as significant as they used to be.

It also has Java-style method names instead of Perl-style method names, which makes me cringe a bit.

But if WebGUI is happy to trust it as their config system, clearly it works very well. And the documentation has improved substantially.

So I'm docking 1 point for the minor cargo-culting and the Java API, but otherwise a solid module when your project will gain advantages by having the config files as JSON.

Proc-Exists (0.90) *

I vote the mathematical opposite of any author's vote as a hedge against (real or perceived) conflicts of interest.

Template-Toolkit (2.19) ***

Template Toolkit is the dominant templating module for Perl, and at a functional level deservedly so.

Unfortunately the author's packaging of this module is highly substandard.

It routinely and randomly breaks on Win32 for months at a time because of weak release testing. When it does break, fixes can take a long time to appear.

Further, it ships with a (fast) C stash that cannot be independently installed after the main distribution, and by default it also ships with an enormous and unrelated HTML GUI toolkit that almost nobody uses, and introduces a number of problems and issues unrelated to the main code.

This is the tragedy of Template Toolkit, that it is by far the best templating module, but the packaging is so annoying.

Acme-Tiny (0.4) *****

This modules leads the way in joke ::Tiny modules.

It makes all the others look like amateur whinging fools by comparison.

I approve.

lib-tiny (0.1)

This is the mother of all stupid reviews. I mean seriously, what the fuck are you on man?

This module, like almost all ::Tiny modules, is intended to save MEMORY, not CPU time.

That said, I don't think this module is appropriate for the ::tiny suffix, as it needs to be "compiled" for a specific architecture and can't be moved afterwards.

PPIx-Shorthand (v1.0.0) ****

I endorse this module.

PPI *used* to have something similar in it to allow for "shorthand" naming, but unfortunately it got removed for speed reasons during one of many optimization runs, and having it inside the API was never really the best place for it.

This helps add the usability at the outside edge of the API, where it belongs.

Only minor nit with this module is that it is OO and requires instantiation, which would seam to involve almost as much typing as it saves.

It would be interesting to see if something equally modular could be done with with an ultra-light interface...

$document->find( qp'include' )

...or something equally thin.

WWW-Mechanize (1.34) ***

In general, an excellent module for dealing with website automation in the region between the jobs that need a single simple stateless LWP::UserAgent request, and the jobs that need full blown JavaScript/browser support.

In general, it does the job very well, and has a reasonably well rounded API.

However, it has a few problems. One small problem, and one medium problem.

The small problem is that in some ways the API can be a little thin. It does the essentials, but sometimes it's lacking a convenience method here or there that would just make using it that much cleaner.

The medium problem is the test suite. It does the job if you are a normal unix situation, with a normal setup.

However, sometimes the test suite generates false failures because it hasn't been built sufficiently robustly.

It uses an internal test server that fails on strange and interesting platforms, like Windows, and it seems to assume a real connection to the Internet, and fails if it can't connect.

The situation is slowly improving, but it still fails on 5.6, it fails a lot on cygwin, and it fails periodically on Win32 native.

Any module with literally hundreds of other modules depending on it shouldn't fail ANYWHERE, under ANY circumstances.

This lets down an otherwise excellent module, and so I tend to reach for vanilla LWP::UserAgent more often that I would like, simply for the improved compatibility, safety, and robustness.

Time-HiRes (1.9712) *****

Superlative module.

Does exactly what it says on the tin, does it well, is expertly maintained, and I've never ever had to second-guess it.

It works, it works well, and it works everywhere.

Nothing-Tiny (1) *

Manages to simultaneously be pointless, while not meeting the criteria for ::Tiny, and failing as a joke. Only succeeds in being a troll.

Moose-Tiny (0.04) ***

(Bumped to three stars, as this has become a useful module for benchmarking Moose performance for a specific common use case when compared to alternative techniques)

Supreme demonstration of ironic naming.

This is quite possibly the first case of the bloated version of a module being created AFTER the ::Tiny module.

This module is perfect for when you want to use 7 megabytes of memory to create an accessor.

HTML-Element-Tiny (0.004) **

While I'm sure this module works just fine, it does not meet the normal criteria of the other ::Tiny modules.

It makes extensive use of 5.006 features, contains multiple classeses inside it, has at least one undocumented dependency, and makes use of weak references (which aren't universally available).

In short, while this seems like a decent enough, it currently does not look like it should be part of the ::Tiny suffix

Test-Reporter (1.34) **

The modules does exactly what it says it does.

Unfortunately, with the entire infrastructure of CPAN test report transport hanging on top of this one module, I find it utterly ridiculous that in this day and age our only option for test result transport is as flakey, unreliable and difficult to secure transport as email.

For example, test reporting on a laptop requires different SMTP MTA setups in different physical locations or your own public mail server, ISPs often firewall outbound SMTP, Windows SMTP can be troublesome, SMTP is not something that can be easily auto-configured and "Just Work" for ordinary users without poking and prodding.

As long as Test::Reporter (the sole module responsible for test transport) continues to implement a transport that isn't so kludgy (for example HTTP), brilliant modules like CPAN::Reporter will remain crippled and unable be able to live up to their full potential.


A few people have asked why such a low score when it works. To clarify, in the current testing system this module is SOLELY responsible for transport. By continuing to stick to only SMTP, I consider this module to be fundamentally failing this responsibility.

Despite working code, the module is not currently fit for task, hence the score. Once resolved, I will be the first to cheer for this module.

List-MoreUtils (0.22) *****

A hugely useful set of utility functions.

Not only do they make your code smaller, but in situations where you have lots of very tight iterative code with many many subroutine calls, they can also make your code significantly faster as well.

The only thing I wish it had would be to let me spell "uniq" as "distinct" in SQL style.

HTTP-Server-Simple (0.27) **

I appreciate this module for what it does, a nice simple embedded web server.

Unfortunately, it does seem to fail to pass tests a fair bit still, and I am not personally willing to risk adding something like this as a dependency until it pretty much "just works".

So this is ok for ad-hoc and in-house testing, but is too risky and not yet trustworthy for anything that will go onto the CPAN.

I'm hopeful that future versions will start to see clean CPAN Testers results, so I can use it for CPAN modules.

Clone (0.24) *****

Clone is, quite frankly, a brilliant module.

I mean, if you want to copy a data structure or something, it doesn't get any better than a single function that can be used as an importable function, non-imported function, or a method, that is fast as hell, acts as only a single debugger statement, and takes up only 13K of memory!

What more could you possibly want? For most uses, it's basically copies in zero time using zero resources, or so close to it, who cares.

However, there is one major caveat. If you are cloning object trees and such, you need to know if Clone will work with the object's classes properly.

For a number of classes, particularly the more complex ones, they cannot be trivially cloned, and require the intervention of things like the Storable hooks.

Because Clone is very naive in this regard, it may not be useful in all cases.

However, if you start by using Clone, it's quite trivial to replace it with Storable::dclone instead. And for people WRITING modules that need Storable hooks or have non-trivial cloning issues, Clone can be used to provide the intial naive clone very very fast, after which you then to the relevant cleaning up.

Perl-Repository-APC (1.251) *****

This module is unbelievably brilliant.

I only wish I was smart enough to be able to use it (the module, not the scripts of course, which make their relevant tasks relatively easy).

IO-Prompt (v0.99.4) **

This is a great module, if you are on Unix.

And for applications which both already are limited to Unix and already require a recent Perl version, I recommend it highly.

Unfortunately, despite the fact it installs on Windows, it doesn't work at all on Win32.

Full marks for the functionality, but loses 1 point for not being cross-platform, 1 for not having any unit tests beyond the boilerplate load and POS tests, and 1 for APPEARING to work and installing despite the fact it doesn't work.

I do not recommend the use of IO::Prompt for anything that might end up on CPAN, where cross-platform capability is needed.

HTML-Tiny (0.10) ****

This module is a good attempt at a super-light HTML library and fulfils all the basic rules of ::Tiny.

My only negative is that by the extreme standards of the ::Tiny modules it is a bit bloated with accessor method overhead, when most of the options probably only need to be set once at constructor time and should just be provided there.

But otherwise, a competent effort.

DBI (1.56) ****

The standard indispensable core of all things database.

The only minor issue I have is with the DBI distribution packaging, which does seem to be bloating out a little in recent times with some features and packages that might be better in a seperate distributions.

Archive-Zip (1.18)

1.20 Tue 5 Jun 2007 - Adam Kennedy

- Removing dependency on File::Which due to public outburst of flaming

on cpanra(n)tings by H.Merijn Brand. Try a simple email next time. :(

- Embedding an entire copy of File::Which inside the tests instead as

an alternative to compensating for the lack of build_requires.

DBD-SQLite (1.13) *****

Together with DBD::Pg and DBD::Oracle, DBD::SQLite is a member of my "Holy Trinity" of database drivers.

The three form a very clean upgrade path from "small embedded database" -> "real database" -> "money is no object" and their SQL fairly easy to port between.

Further, DBD::SQLite follows Elaine's Law to the letter "Just make it fucking easy to install". Matt was one of the first people to use the tactic of just bundling the entire C codebase inside the CPAN module, and this has worked brilliantly.

To take this further, as of 1.13 DBD::SQLite now installs flawlessly not just on Unix, but on Win32 as well, so now it is completely safe to use as a cross-platform dependency on the three major (*NIX, Mac, Win32) platforms.

Bravo Matt!

UNIVERSAL-exports (0.05) **

Written well, and works properly.

But it also causes action at a distance, and it's functionality is not contained.

Unfortunately, as with every UNIVERSAL::something module, it is dangerously octamarine (see Terry Pratchet) and should be used with caution, as when used in combination with other modules that do similar symbol table tricks, there is a random non-trivial chance of it exploding violently without warning.

cwd (HASH(0x896111c)) *

This module should be pulled immediately from the CPAN.

On Windows at least, when it installs it will see as shadowing it, and uninstall it.

This will fatally break the Perl installation on Windows, and quite possibly other case-insensitive platforms.

That says nothing about the module itself, which I actually find myself agreeing with, even it it's simplistic. Sugaring the BEGIN { ... } path adjustment is not a bad idea, and although trivial I'd probably end up using it in some cases.

And the implementation can certainly be improved later.

But unfortunately, this module under it's current name is pure destructive badness. I look forward to a better name.

Data-Pageset (1.03)

The previous version of this review no longer applies, and since I'm not a user of this module, I have nothing to contribute (but apparently you can't delete reviews) :/

Test-MockObject (1.06) ***

Test::MockObject is a great idea, mostly well executed.

When you really get into a jam, testing something very tricky or unusual, it is the veritable knight in shining armor for your testing script. As a concept and for _most_ of its coding it scores a natural 5.

But it suffers from two points, for which I remove 2 points :)

Firstly, it makes use of UNIVERSAL::can and UNIVERSAL::isa. The subject of these two modules is extremely sensitive, and in particular the author and I are the most vocal of those on either side of the (mostly) religious argument on this.

But since this score is opinion-based, I'm taking off a point for insisting on using them, without the option to disable. They modify some of the most core functions in Perl to act differently, which causes action at a distance, and I've been bitten before a couple of times by code (generally very deep or magic code) acting differently just because Test::MockObject was LOADED (without even using it).

Secondly, I'm removing a point because I think the move to up the version to 1.00 is premature. I'd still consider it late beta quality.

I find I can still poke holes in this module and find bugs fairly regularly and fairly easily.

That's not to slight the author at all, who is always quite responsive to fixing the bugs. But I still think bugs are too easy to find to call to consider it production grade, given the advanced magic it is trying to do.

I guess I'd just like to see someone spend half a day or so _intentionally_ trying to break this module with corner cases before we moved it to production versioning.

Because as much as I appreciate the bug fixes, it would be nice if I wasn't able to find them so easily.

Class-InsideOut (1.00) *****

(Updating review now this has reached 1.00)

While I mildly detest the inside-out object concept in general (the number of uses in which is has a positive effect large enough to make up for its negatives being exceedingly small) and recommend against them for all but the most crazy situtations where you asbolutely need to protect your class internals from anything but a PadWalker-weilding maniac, it would seem this author at least understands WHY inside-out objects are so screwed as a concept (cloning, leaking, Storable-incompatibility, Clone incompatibility, and on and on and on) and has gone about provide suitably complete re-implementations of all the functionality that inside-out module lose out on by not being normal.

This module and Object::InsideOut are the only two implementations I would consider safe and solid enough to use in production. And this one is the lighter of the two. Start with this module, and if you need more power trade up later to the heavier Object::InsideOut.

UNIVERSAL-which (0.01) *


UNIVERSAL::anything modules are _bad_.

They pollute the namespace, and cause strange action at a distance.

This module will make any call to a ->which method in any loaded module which goes via an AUTOLOAD fail.

This same functionality would be trivial to add to something like Class::Inspector, without having to muck with UNIVERSAL in the process.

This, and pretty much every single other UNIVERSAL::something module, should never be used in production. There's tentative but reluctant acceptance of UNIVERSAL::isa/can because they CHANGE the behaviour of existing functions, but even they do not ADD to the APIs.

This module, along with things like UNIVERSAL::clone, do not belong on CPAN.

Task (1.01)

To respond to Darin from the author's perspective, I personally went through dozens of possible names, and the mailing list pulled out the thesaurus and went through many more.

Task was used in the end because it's a closer description than Bundle, it is NOT currently in use by CPAN modules, it doesn't have DIRECT associative computer science meaning that would justify keeping the name free. Although it is used quite a bit in computers, most uses of it are so generic or context specific to make the use of Task:: too confusing.

And finally there was an analogy that could be made with the task_foo series of debian packages, where a Task module would be what you do to achieve a general task like "setting up Catalyst" rather than installing a specific package of code.

It was the best of a bad situation. If anyone has alternative and better names, I would love to here one. Because the term Bundle itself is wrong and often misinterpreted.

Data-FixedFormat (0.02) **

Checked this out while evaluating fixed-length parser generators for a work project.

It looks like a fairly nice API, but be aware it has absolutely NO tests at all, other than a single "does the module compile and load" test, and so using this for a serious project would be considered high-risk.

Scalar-List-Utils (1.18) ****

Scalar::Util and List::Util are some of the most useful and most depended on modules in CPAN. They help to increase the clarity of many expressions, especially when you know what exactly what you want to do, and Perl's DWIM'ness starts to get in the way a bit.

The annoyance with it not having any/all functions has gone now we have List::MoreUtils.

The one remaining annoyance with this module, is that as new functions have been added to Scalar::Util it is not always clear WHICH functions are available in what versions and on what platforms. For example, on some platforms weakrefs are not available, even though that version is supposed to support them.

As a result you often need to write unit tests to double check that Scalar::Util has the functions you need, especially as I mentioned for things like weaken.

UNIVERSAL-isa (0.06) *

Everyone deserves a second chance, so I've ditched my original review and re-evaluated this dist.

Firstly, let me say that it is well and truly agreed (by people that understand the way that the can/isa methods works) that calling them as a function is bad.

However, as someone that learnt it the hard way themselves, playing games with UNIVERSAL is frought with peril, and should always be undertaken with humility, a strong concern for corner cases, and a perfectionist attitude.

The (original) author continues to display an unwarranted attitude of superiority, WITHOUT actually being superior. He insults Perl authors in the abstract, and then proceeds to make mistakes in UNIVERSAL::isa. And worse, without realising he's making the mistakes.

My original example of UNIVERSAL::isa(undef, 'Foo') dying was just that, an example. While it may now be fixed, the attitude that _caused_ that bug continues, and so a quick read of the source shows further obvious bugs.

For example, this distribution doesn't just warn about bad UNIVERSAL::isa usage, is disables any correct usage of UNIVERSAL::isa altogether, when an approach more in tune with the rest of Perl would be to warn and then allow the bad use anyway. (because Perl in general has the attitude of people not using strict and warnings do whatever they want with the rope, including hang themselves)

In the 1% of cases you ACTUALLY need to use UNIVERSAL::isa directly, you can't lexically disable warnings, and then call UNIVERSAL::isa and have it intentionally ignore overloaded ->isa methods.

As just another example, UNIVERSAL::isa is not reentrant. It stops infinite loops by means of a global $recursive variable. This means that if an overloaded ->isa method itself uses UNIVERSAL::isa then the global variable is incorrectly set, and any overloaded isa method in that second call is NOT called. This means that methods act differently depending on where they are called.

This stems from the continuing arrogance displayed by the author, which has resulted in him doing only relatively light unit testing that ignores vast numbers of cases in which there might potentially be problems. In addition he only tests for true results, with no testing for correct failures to catch problems that might stem from false positives.

So 1 star removed for insulting and unhelpful documentation, 1 star for only doing trivial unit testing, 1 star removed to balance the author 5-star rating himself when CPAN Ratings allows an undef rating specifically for the author to respond without a conflict of interest, and 1 star removed for both preventing legitimate uses of UNIVERSAL::isa and making isa no longer reentrant.

People in glass houses shouldn't throw stones.

I should note that the current maintainer, chromatic, is not who I refer to above. Although he has mis moments as well, he generally accepts legitimate criticism quite readily and improves things.

I've added back a start for fixing the documentation, but I'd still much prefer to see a warnings::isacan that warns but doesn't change behaviour.

IPC-Run3 (0.034) *****

This Just Works. Everywhere.

This is pretty much THE standard basic way to lunch a system command, with or without input, with or without output and error.

While it's not quite so obvious and useful for things need interactive and Expect-like behaviour, for any command that goes to the system and doesn't need to be interactive this is almost always what you want to be using.

version (0.53) **** is a great idea. If was far better to build proper version support into Perl via a standard version module, rather than in the language itself.

And having it as a standalone dist has meant the concept has been able to develop and break as needed without hurting anyone.

It also works pretty darned well now that it has had time to mature. I'd call it late-beta quality, and ok for use in your code.

That said, I do agree with the Module::Build pains. I don't blame for M:B's problems, only for choosing to use Module::Build before it is finished, stable and in the core.

Modules that are going to become extremely heavily dependended only really should go for compatibility (including backwards compatibility) and pragmatism first, even at the expense of a bit more work writing the installer.

So a one star penalty for inflicting M:B's pain on a lot of people, but apart from that a perfect score. It is certainly The Right Way to solve the versioning problem.

Module-Build (0.35) ***

I get the point. I even like the idea. But Module::Build has been promoted as being usable for some time now, when it (to me at least) still seems to have icky problems.

For starters, every Module::Build script seems to blindly assume that M:B is already installed, something that it isn't on new installs, or new installs of older Perls.

So if you install something with the normal Makefile.PL and some dependency of a dependency uses M:B boom it dies.

Second, it doubles the configuration load... and asks almost all of the same questions about configuration. Or at least, that seems to have been forced on both and when dealing with configurations.

Then there's the problems with it not more-closely matching the way EU::MM does things like PREFIX. When faced with the PREFIX problems, Module::Build presents a long lecture on why PREFIX is bad, and proposes a different mechanism that is COMPLETELY incompatible with PREFIX. This makes the 10% of CPAN that uses Module::Build incompatible with the other 90%, and thus breaking 10 years of accumulated core and third-party toolchains, not to mention the built up knowlegde of millions of Perl programmers and sysadmins.

In addition, Module::Build-based modules are unable to bootstrap, since they rely on Module::Build being installed already, and in addition Module::Build has zero back-compatibility capability in it's design, something the author admits in his Motiviations section.

It really comes down to too many people promoting the user of pre-production beta software. See that version number. It's for a reason. I'd recommend most people to go away and wait until it is bug-free and hits 1.000. Unless you really absolutely have to do something madly custom, then use it. But otherwise wait.

IO-String (1.08) *****

This is very similar to another class IO::Scalar that comes in the io-stringy package of handle-munging modules.

But having used both extensively, let me say that this is FAR more accurate. It looks and acts exactly like an IO::Handle, even to the point of correct seeking and seek-after-end automated-null-inserts behavior.

IO::Scalar has a number of ugly things that means it doesn't behave like an IO::Handle when you really really need it to be exactly like a real handle.

So don't use IO::Scalar, use this. It seriously kicks ass.

File-HomeDir (0.52)

(Response from this modules new maintainer.)

The below review for 0.06 no longer applies as this module has been rewritten from scratch since being taken over and does correctly support Windows + Mac OS X + Unix. (and adds newer cooler functionality to boot)

Finance-Bank-AU-StGeorge (0.01) ***

This module doesn't seem to work, and it's documentation is non-existant (tested 0.01 on Jan 4 2006)

However, reading the code it does seem that he DID actually implement it, and that it USED to work, which is amazing in and of itself given that St George's online banking is a Java Applet that I'd written off as not implementable.

So my 3 star rating is for the balls to try to do it, and the realisation that it could be done.

If the author maintains this module, it goes up to 5.

UNIVERSAL-clone (0.01) *


This is one step too far!

UNIVERSAL::isa and UNIVERSAL::can both attempted to "repair" a (certainly) percieved and (arguably) real problem in the way some authors did their "isa" and "can" checks.

While the implementations where ugly, there was _some_ justification for their existance.

Modifying UNIVERSAL is a strategy of LAST resort.

It creates action at a distance which can and does break things and should NEVER be used when any other alternative is available. Witness SVK's problem with PAR because they used the Class::Autouse superloader (which uses UNIVERSAL and recommends against anyone using)

This module modifies UNIVERSAL and creates action at a distance for a mere convenience, and a bad one at that.

It should _never_ be used by any module, and only serves to complicate matters when a simple case by case "use base 'Clone'" or "use Clone 'clone'" would be sufficient.

This module really should not be in CPAN all, as it only serves to encourage people to use it, and encourage even more people to write modules that modify UNIVERSAL proudly, when modifying UNIVERSAL is something that should be done in secret and without mention.

Every modification of UNIVERSAL is a failure to implement what you want in less than evil way.

HTTP-Body (0.5) ***

This class does something. I'm sure of it. And it looks like it is written in such a way as I might want to use it.

I'm just not exactly sure WHAT it does.

The documentation is terse to the point of useless, and seems to implement things like spin-locking of something (except there's no code in HTTP::Body to implement whatever it is locking)

I dunno...

XML-SAX (0.13) *****

This module is how you do non-trivial XML "properly" in Perl.

Although there's a bit of a learning curve at the start, and you can't do much until you sort out the somewhat fuzzy SAX terminology, this is functionally and in all other ways an excellent dist.

It's easy to install, it's very easy to write simple Parser, Driver and Filter classes, and it feels designed to scale well.

It's very easy to use this it to build the "next bigger thing" or embed XML support into projects. It doesn't feel as if it imposes on you at all.

And with the use of XML::Schema::Validator to prevalidate the XML structure, it makes it extremely easy to build parsers by sacrificing size for simplicity. You parser code might be a little long and a little boring, but it's not at all complicated, and becomes very easy to maintain.

Kwiki (0.38)

Ignore the previous Kwiki commentor poster. It's a complete troll.

MediaWiki is a giant bloated PHP application specifically created for Wikipedia. Kwiki is a relatively light-weight, extremely pluggable _Perl_ application.

It's rediculous that cpanrantings is being used to promote PHP applications.

I think the weather plugins are silly too, SO I DON'T INSTALL THEM. Of course, the lack of Kwiki::Publish is an entire other problem :)

If we've got any moderators for this site, please delete the previous post (and this one too when you do).

Class-DBI (v3.0.8) ****

I'd previously called Class::DBI abandonware, due to an 18 month drought of releases and the seemingly bizare refusal of the author to integrate and release bugfixes the user community were sending in.

It also does some tasks quite a weird way, in particular the LiveObjects system can lead to some fairly ugly situations/bugs, and it isn't possible to create a new object and pass it around to be worked on _before_ the first commit to the database.

(Most other systems I've seen have some sort of ->store method which does either ->insert or ->update depending on whether the object is new or not).

HOWEVER, now that the release drought is over (and how!), and the author has become much more response (if only to I think most of these problems will gradually be fixed.

Class::DBI seems to be alive again, and so I'm happily rerating it. Bugs and nigglies aren't anywhere near so much of a problem when you know they are going to be fixed.

EvilBoss (1.01) **

The code looks clean enough, but of course there's zero documentation. All I can tell is that it's something to do with FidoNet... perhaps for building FidoNet agents?

Archive-Tar (1.26) *****

Archive::Tar is one of those modules that you just use and never really think about. But it's a really an amazing workhorse. It does it's job quietly and with no fuss whenever you need it, but behind the scenes it handles all the obscure, diverse and weird "enhancements" that so many different people have added to the .tar format.

And unlike many other modules in areas where there isn't a lot of chance for closure, it is actually maintained well.

Kudos Jos

Module-Install (0.37) ****

Module::Install is a great module, but for a while there it seemed to have been abandoned.

It still has quite a number of outstanding bugs, but I spose I can't really complain about these any more, given that I've got commit rights to the repository now :/ And I believe the author is willing to do the same for others who want to address these bugs.

Still, you might want to be careful if you want your module to support lower than 5.6.0, and the documentation can get a bit weak.

But all in all I now think that with enough users and more attention, these bugs can be resolved. The idea and the design are completely sound and have always been so, it just needs some TLC here and there.

YAML (0.70) ****

(Update: Now that I am, temporarily, the maintainer for this is CLEARLY deserves a better score)

Yet Another Markup Language (YAML) was a great markup language. A way to handle scalars, array, hashes and multi-lines in a human-readable form, and move to and from data structures easily, theoretically in many languages (I have no experienced in this regard).

The best comment I ever heard was "It's great, we just spit out our nightly processing run reports in YAML and the bosses secretary can read them just fine".

Except that somewhere along the way, it would seem the dream was lost. Instead of a straight forward documents<--->struct language, we are seemingly now left with a multi-doc-per-file data serialization language with all sorts of nasty holes in it.

In attempting to become all things to all people, it has become a failure at all of them (except possibly as a debugging data dumper).

It fails as a simple markup language, as it now supports structures and notations that humans have trouble understanding, especially non-technical humans.

It fails as a data serialization language. You simply can't serialize all the oddities of Perl data structures, such as circulars and objects and overloads and so on, without extensive work, and the assistance of those classes.

Storable does these tricky bits right, but it's taken years. Adding support for Singletons to Storable alone took several months, involved 4 people, and produced what is probably the largest comment trail of all time (Bug #4901)

YAML just blindly blesses things into classes, regardless of whether the class can support that, is loaded, or even exists.

Support for complex Perl structures also pretty much kills comprehensive cross-language support. The largest gripe that the Python people have with the JavaScript Archive Network is it's use of YAML.

You cannot implement Perl-complixity serialization without class hooks, and you can't sanely implement class hooks in any sort of cross-language fashion.

Noting the 4 outstanding bugs rated "Critical", 12 rated "Important", and about 15 other smaller ones, and as much as it pains me to do this, I have to rate YAML as a failure.

And given the mission it has now set itself, I cannot see it ever being able to succeed. There are too many irresolvable paradoxs.

I'd greatly like to see something that addressed the original goal... perhaps "YIML - YIML isa Markup Language"?

Sub-Installer (0.0.2) **

This module provides a mechanism for simplifying the process of manipulating the symbol table to add or replace functions, and I'm sure it works completely correctly given the author.

However, to support a slight saving of characters it uses the extraordinarily evil trick of superclassing UNIVERSAL.

Playing games with UNIVERSAL is normally a strategy of last resort, as it can cause unintended results in other modules, and having more than one module that does things to UNIVERSAL can often result in strange bugs, race conditions and corner cases.

I would score this at 2 stars not for the use of UNIVERSAL this way, but for doing it for such a trivial gain in functionality. There are a number of other ways similar functionality could be have done done that would be just as clear, and wouldn't involve increasing the potential for collisions with other modules.

The use of this module should be discouraged for anything larger than trivial scripts, particularly once you use a significant number of other modules. And the creation of any module with this as a dependency is highly discouraged. Do you own symbol table manipulation. Cut and paste from inside it if necesary.

Another star is removed for the seemingly unnecesary use of a three-part version and the use of in an environment (CPAN) where reduction of dependencies and back-compatibility is encouraged, and without even listing it as a dependency.

Time-Traveler (0.01) *

Great idea, terrible name! :(

CPAN (Acme:: aside) is generally not the place the cutsey module names. Some of these are relatively harmless, but when you put the module inside a top level namespace that is completely unrelated to it, it is most certainly not harmless.

Time:: is for time-related modules. Yours doesn't seem to be time-related at all, the module name is almost just "branding".

As cool as it sounds, please move this module to either Acme::Time::Traveller (if it's meant is a demonstration of a neat trick) or Data:: or Scalar:: or somewhere else more appropriate.

perl-tutorial (perl-tutorial_2.0) **

For a package to name itself "perl-tutorial" and number itself version 2.0 it was quite surprising to find that it wasn't in English, the common language for Perl documentation.

While I have nothing against the package itself, I would have expected that a) The tutorial supported multiple languages, or b) That the language was clearly labelled in the package name.

perl-tutorial-de perhaps.

Transform-Canvas (0.003) **

(I have no opinion on the function of the module)

Transform::Canvas appears to have been added to CPAN very (overly) hastily.

Much of the documentation has not been changed from the default hs2xs. "Perl extension to blah blah blah". "It looks like the author of the extension was negligent enough to leave the stub unedited."

In addition, the choice of name is quite poor.

The module name shows both the incorrect order (Verb -> Noun instead of Noun -> Verb) and is in a non-standard unused location (Transform::...) which adds a new root namespace unnecesarily.

Highly recommend not using this module at this point, as it is likely to be moved to a different namespace.

(I'd expect something more like Algorithm:: or SVG::Math:: or something similar).

Java-Swing (0.02) ****

To be frank, I haven't used this module and probably won't get the chance to any time soon.

This review is purely to complement the balls and skill required to pull this off. The code looks clean and well structured, and DAMN he's had to write a lot of it.

Now, if there was an easy way to replicate this process for any arbitrary multi-class Java API, that would be even more amazing.

Proc-Application (0.01) **

I have no opinion on Proc::Application itself.

My main problem with this dist is that when I went looking for some class to create process locks I found Proc::Lock and Proc::Lock::File, which seemed like something I could either use, or build on.

However, they don't exist as a seperate package, only as part of this "application framework"-esk package.

Things that have value outside the context of a framework should not be in the framework distribution, they should be separated into another package.

The only things that should be "stuck" in a framework are the parts that are intrinsicly linked to the framework as a whole, and will not function without the framework.

Class-Autouse (1.26)

(Full Disclosure: I am the author of this Module)

This was the first module I ever wrote for CPAN, and now sits at the core of every large API I create. It has dealt with class trees as large as 200-300 classes, and has been flogged to death and tested in almost every way I can imagine.

I highly recommend this to anyone loading lots of large modules they might not use, or loading very large class heirachies.

HTML-Merge (3.48) ***

I have no opinion on the function or usability of this module either way... but it has quite possibly the most annoying NAME section of any module in CPAN.

The NAME section is intended to hold the module name and a short description of the module. Instead of a description the author has inserted an annoying copyright notice instead, which looks completely wrong on places like the CPAN recent uploads page at

The author should revert to using the NAME section for a short description like the rest of CPAN and leave copyright notices to the COPYRIGHT section.

File::Type / File-Type (0.22) **

Before I begin, let me note that I use this module myself and in functionality terms it should probably score 4 out of 5.

As a campainer against module bloat I find this module rather offensive. The author has taken 128 magic entries (compared to nearly 5000 in /etc/magic) and converted them to rather verbose Perl and loads all of it for the entire time the program is running.

The result? 1.5 meg of RAM to check 128 file types. I would imagine this would mean that to check to the same depth as /etc/magic you would need 50 meg of RAM in order to load it all.

In addition, the tests are in no particular order. I'm not sure whether or not order is important in the source database, but I imagine it would get quite slow when you need to get to entry 50 or 100 just to detect a common file like a .gif.

What maybe the author needs to do is to start with inline code for the most common 10 or 20 file types (gif, jpg, mp3, Word doc, etc) and then load the database in and process it in interpreted form. To help with the load issues, he could compile the code for any file type found and add it to the list of inline tests.

So, a good idea, executed with no respect for system resource, with this score given on that basis.

List-MoreUtil (0.01) *

I first found this module after I installed it by accident when trying to install List::MoreUtils. Why pick a name so close?

What has made List::Util and List::MoreUtils to powerful and useful is that they are implemented in C and are fast, fast, FAST! List::MoreUtil does not do this.

In fact, it appears to duplicate many of the functions that already exist in List::Util and List::MoreUtil. In that sense, it seems out of place and greatly duplicates existing work.

Although the List::Util maintainer is a bit touchy about adding additional function, the List::MoreUtils maintainer certainly isn't. There's no reasonable that some of the more interesting functions here couldn't have been added to it initially in Perl with the aim of converting to C in the long run.

In it's current form I think this module may actually cause more harm than good. Since it appears to be relatively new, I recommend removing it outright before anyone creates a dependency on it.

Perhaps a more private namespace like Author::ERIC::ListUtils would be more appropriate?