Reviews by Steffen Müller


LaTeX-TikZ (0.02) *****

When Vincent first told me that he was working on writing a Perl module for generating TikZ, I was very excited as I had myself been generating a lot of graphics using it. By the time he finished a first version that he felt comfortable releasing to the public, my heaviest uses of TikZ had passed, so I only ever got the chance to play with the module a little.

Just recently, I had the opportunity to use it for generating math challenges for my fiancée, who is a teacher: Picture a little maze full of numbers and the kids' task is to find a way to the exit that adds up to certain total. With LaTeX::TikZ, after learning how the module works, it was almost too trivial to write a program that would generate arbitrary numbers of maze problems.

As with all Vincent Pit code, this is a well written and thought out piece of software. Can't recommend it more highly!

PerlIO-Util (0.54) *****

PerlIO::Util is one of those simple gems that make your life easier. It provides a couple of PerlIO layers (think open() modes) that are damn convenient. Maybe it's best to give an example, this is for file locking:

use Fcntl qw/:flock/;
open my $fh, '<', "file" or die "Some error: $!";
flock $fh, LOCK_SH or die "Could not get lock on file 'file': $!";
close $fh;

becomes simply

use PerlIO::Util;
open my $fh, '< :flock', "file" or die "Some error: $!"
close $fh;

and it checks your open mode to see whether you'd need a shared or exclusive lock. Also, no magic constants from Fcntl. Not a big deal, but just one less thing to worry about.

pip (0.08a)

This is just a quick answer to Mark's comment: PAR::Packer is there to help with bootstrapping this. "pp -o pip.bin pip"


version (0.6701) *****

I had to compare versions in PAR::Repository::Client when determining the prefered PAR distribution for installation. Without that would have required a lot of thought and quite a bit of code to get right. In fact, it might have required most of what version does. Unfortunately, because of the pest that are X.Y.Z versions, by definition can't make comparisons work well in all cases, but certainly in all but the most obscure ones.

Thank you, John, for helping me retain a bit of sanity by not having to think about version comparison (too much). Your work has cleaned up a lot of cruft.

Statistics-R (0.02) *

I've been looking for a way to use the powerful "R" package from Perl for a while. There is an "RSPerl" package which does various XS tricks to support a bi-directional interface. Unfortunately, it is not installable from CPAN and does not work on non *nix systems. Then, there is Statistics::R.

Generally, I don't like those flaming, unproductive 1-star ratings which bash other people's hard work. But now and then, I come a cross a module that just scares me. Here is why:

Statistics::R is an interface to the R library which opens the R shell via pipes and sends plaintext commands to it. Now, this is probably the worst way to interface to anything, but sometimes it's also the easiest by far. Oh well. This wouldn't have been as bad if the module wasn't doing downright weird things internally. Here's a gem:

$this->{HOLD_PIPE_X} = ++$HOLD_PIPE_X ;

*{"HOLD_PIPE$HOLD_PIPE_X"} = $read ;

Uh, $this is a, umm, global variable. Yes, you read correctly. The package implements singletons via a single global variable. The horrors don't stop there either: Each and every method/subroutine contains a 2-3 line copy&pasted header to make this work:

sub error { my $CLASS_HPLOO ;$CLASS_HPLOO = $this if defined $this ;my $this = UNIVERSAL::isa($_[0],'UNIVERSAL') ? shift : $CLASS_HPLOO ;my $class = ref($this) || __PACKAGE__ ;$CLASS_HPLOO = undef ; &Statistics::R::error ;}

Note that unless cpanratings formats the code differently, this is the original format.

If, for some reason, the R interpreter refuses to start, which happens on Linux with any reasonably recent version of R, the method that starts the R interpreter loops forever with a test for a PID file and a select statement inside. Ouch.

Finally, there are various unanswered RT tickets. (Including two mentioning the bug outlined above.)

As much as I would like to use this module and as much work as it might have been writing it, this is not production grade code. I suggest you stay away unless you have no choice. Sorry.

Imager (0.51) *****

I had originally reviewed Imager in 2003. It was wonderful then, but it has come a long way. Particularily, I am now able to compile it on Windows and write fast (and simple) XS extensions for it.

Addi has put a lot of work into this impressive package, but the current maintainer, Tony Cook, has done miracles.

Imager has become a great replacement for GD and ImageMagick and feels much better integrated into Perl, the language, than either of them.

The original review is retained below:

Imager is the graphics module I had been waiting for.

It's easy to use and has a great interface. It's more powerful than ImageMagick and GD. Plus, it's fast and portable.

I've been using Imager in quite a few of my modules directly (Math::Project3D::Plot, etc.) or indirectly by suggesting the user go with it for visualization (Physics::Particles, Physics::Springs, Physics::Springs::Friction). I originally used GD and ImageMagick, but both of those modules/libraries had certain drawbacks. Imager was the natural replacement.

Getopt-ArgvFile (1.10) *****

This is a module that does one simple thing and does is well: It offers facilities to read command line options from a file. This feature is easy to understand for users and developers alike, but simple-minded implementations are probably ripe with pitfalls.

Adding support in one of your applications just means adding a single "use Getopt::ArgvFile;" line before "use Getopt::Long;". The default behaviour of this module is sane but if you need to do something fancy, the documentation tells you exactly how it can be accomplished.

Thank you for this contribution to CPAN. The next release of PAR will use it. And at virtually no development cost for us maintainers, too!

YAML-Syck (0.42) ****

YAML::Syck isn't only faster than the original YAML module (because it's mostly C), it's currently also more complete.

I haven't had any problems installing it on any Linux system. The same cannot be said about the original YAML module. A PPM package of the current CPAN version is availlable from ActiveState, so even Windows users can start using it right now.

It lacks on the documentation side, but documentation is something Audrey's modules have sometimes been shipped without in the past. The YAML format is reasonably documented elsewhere and the interface is simple enough, so this only removes one star overall.

Great work, Audrey and why the lucky stiff (who wrote libsyck).

(On a side note: For those who don't want any C/XS or who want something more simplistic, check out Adam Kennedy's effort to write YAML::Tiny. Also, there's YAML::Lite which I haven't tried yet.)

Task (1.01) *****

Darin McBride's recent rating prompted me to write an answer.

I agree that the idea is sound. A "bundling" system that doesn't require extra magic from the installation system which the client uses has long been overdue and I have successfully used Task::* bundles.

The namespace has undergone some significant brainstorming. I witnessed that. I think Adam made a good choice with "Task". Furthermore, it is, to my knowledge, not directly connected to a concept from computer science which ruled out a couple of other good suggestions.

Chart-Graph (2.0) *

The recent review of this module reminded me of the fact that the Chart::Graph::Gnuplot module is severely broken.

Some time ago, I started using it on an old debian/woody box. It worked as advertised. But then, in the transition from gnuplot 3.7 to gnuplot 4.0, (which most likely occurred in a woody->sarge dist upgrade) the module just stopped producing any meaningful output. I sent mail to the authors and created an RT ticket:

I offered to fix the problem and upload a new distribution to CPAN. I have never received an answer.

The problem is really an incompatible change in gnuplot. The transition from 4.0 to the current development version will bring the same problems again, even if the current problem will be fixed. And then, one would have to keep the old interface for users with the old gnuplot binaries...

Ergo, you shouldn't use this module in version 2.0 or earlier (which is all that's availlable right now). If it works for you, it is unlikely to keep working in the future!

Math-Combinatorics (0.03) *****

Combinatorics is something done wrong by many people. They talk about permutations when they really mean combinations and vice versa. Implementations - while they should be rather simple and straighforward - have an unnatural tendency to be buggy or eat your memory quickly (due to the large problem space).

Thus, Math::Combinatorics is a worthy addition to CPAN. It has thorough documentation with references to literature and related modules.

My only gripe is that the tests could be a little more exhaustive.

Thank you, Allen.

Acme-OneHundredNotOut (100) ***

Dear Simon,

being a superior programmer, you have given much advice to me and others. You have released a tremendous amount of work to the public via CPAN. But is it really necessary to... present your work and yourself in such a way as you do by releasing this document by the means of CPAN? I wouldn't normally write this in a publically visible place, but then again, I guess that is what the document provokes. I could think of a million more modest whilst more effective means of giving a history of your contributions to CPAN.
Start by offering the essay on your web page. If you feel the urge to, link it in the documentation of your modules.

Other than that, Sam Vilain summed up my feeling about this very well with his Ghandi quote.

Class-DBI (0.96) ***

Class::DBI is a work of beauty. It makes using databases really convenient and offers elegant ways of specifying data relationships.

The one big gripe I have about the module is the speed hit that comes with the elegant interface. The module takes forever to compile, but that's what we have mod_perl for.

I'll give an example: If you fetch more than a thousand or so records from a database and access their attributes, you'll end up calling numberOfRecords * numberOfAttributes accessor methods. On my humble server, that means waiting 10 seconds for the records to show up in my browser. 8 seconds of those are spent accessing two attributes of 1344 records. (Those 8 seconds are accounted for just by the method calls.)

I was unable to make the program run fast enough using Class::DBI. Thus, I switched to plain DBI and the request now takes significantly less that a tenth of a second to complete.

File-Temp (0.16) ****

File::Temp is temporary file handling done right. It takes care of all the annoying bits that make dealing with temporary files a hassle. In particular, I find temporary files indispensable for atomic writing to data files that might be opened by other (less careful) processes.

The interface of File::Temp is a bit odd. KEY => value pairs in all caps don't feel natural to me and a couple of for historic reasons differently named functions doing basically the same thing aren't at the height of interfaces in my opinion.

I would be able to do the temporary file handling without the module pretty well, but it would cost me significantly more thought. But just a few years ago, I mightn't have known about all the weird things that can happen to a simple-minded approach. So: (File::Temp)++

Math-Algebra-Symbols (1.04) *****

Math::Algebra::Symbols is a (to me) new way to deal with symbolic math in Perl. I did myself spend a considerable amount of time thinking about the subject (the result of which is represented by the Math::Symbolic module) and really liked the more transparent interface of Math::Algebra::Symbols. However, I think it may become limited by the number of overloadable operators and contexts in the future and increasingly convolute the callers namespace.

Since the two aforementioned modules cover much of the same ground, it's probably a good idea to compare them. Math::Symbolic is a much more abstracted attempt at a computer algebra system and thus has a much steeper learning curve. To get started with Philip's module, all you need to know is how to construct a Math::Algebra::Symbols object and most of the rest is done by the overloaded interface. The preferred method of constructing a Math::Symbolic tree/expression is, in contrast, to use its parser. Since Math::Symbolic tries to adhere to object-orientedness as much as possible, Math::Algebra::Symbols is faster for symbolic transformations, but lacks an option to translate a symbolic expression to a fast Perl subroutine or even inlined C for doing many evaluations of the algebraically transformed expression with different variable bindings as required by, for example, a function plotter. Since its normal use is much closer to ordinary calculations in Perl, Math::Algebra::Symbols is also better at cooperating with other mathematical modules like Math::Complex or Math::BigInt. (It's possible to use those modules in conjunction with Math::Symbolic, but more complicated. Please refer to the distribution's examples.)

I really like Math::Algebra::Symbols and will try to work with the author for the benefit of both symbolic math packages.

Test-Distribution (1.14) ****

Test::Distribution checks for several important gotchas many authors tend to overlook. (Particularily those who haven't released much to CPAN yet and thus don't have much experience with creating distributions.)

These include: pod errors, inclusion of all use()d modules in the prerequisites section of the Makefile.PL or Build script, signature, the existance of important distribution files like README, Changes, etc., versions in all included modules, and that all enclosed modules load okay.

Using Test::Distribution isn't hard either. Just copy its synopsis to a t/something.t file and you're done. Most of the time, anyway. Sometimes, you'll want to configure the testing process, but unfortunately, Test::Distribution isn't too flexible about that. You can specify certain types of tests to carry out or not to carry out, but that's all.

One problem I found while using Test::Distribution was that it gets the files to test from some File::Find magic instead of the MANIFEST. I think it should use the files in MANIFEST by default and revert to testing all files in the directory only if MANIFEST doesn't exist. It should issue an optional and non-fatal warning if MANIFEST and the contents of the build directory don't match. Or one should be able to explicitly tell the module which pm and pl files to test.

For example, one of my development directories contains a script that generates some code required for a new module release. That script uses to get the module's current version from META.yml and includes the version number in the generated code. Trying to build the module in that directory throws a Test::Distribution error: "YAML" isn't listed as a prerequisite for building in the Makefile.PL.

Regardless of the problems I faced, the module is a step in the right direction and I will be using it for my non-trivial distributions in the future.

Pod-Coverage (0.12) *****

Pod::Coverage is a very useful module that, when used in another module's test suite, should help improve that modules documentation by a great deal. Of course, developers are free to insert empty documentation stubs for their methods, but those willing to do that don't need Pod::Coverage to remind them of the lacking documentation in the first place.

Math-MatrixReal (1.9) ****

Math::MatrixReal has good documentation and a very good interface. It's intuitive to use and uses algorithms that generally have a low complexity.
Albeit I rate the module to five points in docs, interface, and ease of use, it's getting only four "overall" because, it just doesn't live up to the mightily complicated PDL in terms of speed. (Of course, the authors never claimed it did anywhere close to the same things.)
In conclusion, Math::MatrixReal is great if you're dealing with smallish matrices, but IMO won't cut the mustard in terms of memory efficiency and speed. It's pure-Perl after all.

Math-BigInt (1.65) ****

This is in appreciation of the work Tels and many others have done to all the Math::Big* modules.

While I don't particularily consider BigInts and similar to be completely intuitive to deal with, Math::BigInt does the best it can to hide complexity using Perl's builtin facilities. I've needed arbitrarily precise and/or large numbers in some projects and would have had to switch to a completely different programming language (here: Haskell) if not for this module. Due to Tel's hard work, it's surprisingly fast, too!

Getopt-Long (2.33) *****

Getopt::Long has been in use in my programs for a long time now. It has been suitable for all the command line parsing I have ever had to do and worked with anything I could throw at it through various shells. It works well with Getopt::ArgvFile.

Unlike more complicated command-line parsing modules like Getopt::Declare, Getopt::Long has a rather intuitive interface and doesn't require 1500 lines of documentation (as Damian put it).

I also tried some of the simpler wrappers around this module like Getopt::Simple, but while they worked fine for what they *could* do, I needed the power of Getopt::Long and actually find its interface good enough that it doesn't need simplifying wrappers.

Parse-RecDescent (1.94) ****

Parse::RecDescent is a great module.

It's saved me a lot of time when writing the parser for the Math::Symbolic module. In fact, I doubt there would be a parser for the Math::Symbolic module if there hadn't been Parse::RecDescent to do the difficult work for me.

Writing P::RD grammars needs a bit of time to get accustomed to if you know yacc, but once you get the hang of it, it's not too difficult.

The one main gripe I have with this module is its speed. Compiling parsers takes forever. (As of version 0.112, the Math::Symbolic parser took about a second to compile on my 2GHz machine!) Parsing isn't blazingly fast either. Especially with long input strings.

PAR (0.92)

(Update: I have since picked up PAR as a maintainer and thus removed the rating. I'm keeping the old text as it still applies to Audrey's work!)

Audrey did a good job with PAR. It's great!

Personally, I have been waiting for something along the lines of perlapp/perl2exe (or perhaps even a working perlcc) to be released as open source. PAR exceeded my expectations in that it is much more flexible and powerful than I would have dreamed.