Reviews by Ben Bullock

cpanratings
 

RSS

Font-TTF (1.04)

This module is virtually undocumented. It's probably a great module and does everything, but with documentation this minimal, I'm left with the options of either (a) reading the source code and the Apple TrueType manuals and trying to work out what this does (b) reading the Apple TrueType manuals and just writing the bits of code which I need to do the jobs I want to do. For me, (b) is probably going to take less time and be less frustrating.

The core documentation, Font::TTF::Manual, really tells me next to nothing about what the package does, instead it describes architectural decisions made when designing the module. There are scraps of information in each of the submodule documents, but it's just not enough to get started.

Which is a shame, since the module looks like it's really comprehensive. If the authors would like people to use this module they should try to rewrite the documentation from the user's perspective.

IO-Compress (2.064) *

The IO::Compress::Gzip and IO::Uncompress:Gunzip parts of this module have extremely serious performance issues. I strongly recommend considering alternatives.

Lingua-ENG-Inflect (0.0682) *

This is an exact copy of another module, Lingua::EN::Inflect, version 1.891. The only thing that was changed between the two modules is the name, from "EN" to "ENG", the version number, and a line "use 5.10.1;" at the start of the module. Beyond that there is quite simply no difference whatsoever, the code is identical. Try a diff on these two files if you doubt it:

cpansearch.perl.org/src/DCONWAY/Lingu...

and

cpansearch.perl.org/src/PETAMEM/Lingu...

Since this module was released, the original Lingua::EN::Inflect has been updated so the source code no longer resembles it.

I recommend people to choose the original Lingua::EN::Inflect over this rather pointless fork.

Lingua-JPN-Number (0.0682) *

This module is an unnecessary fork of a module which was superceded.

If you need to process Japanese numbers, I strongly suggest using "Lingua::JA::Numbers" by Dan Kogai rather than this fork of a superceded module.

Lingua-ZHO-Numbers (0.1106) *

This is a fork of another module, Lingua::ZH::Numbers. However, the fork is broken. Whatever has been changed has not been documented, the documentation is just the original, even though it doesn't describe the module contents. It says that the "PetaMem" author has taken over maintenance from the original author, but if so why not get co-maintainership rather than fork to a confusingly similar name?

Considering that the original module still works and is documented correctly, and doesn't seem to have any outstanding problems like a huge list of bugs on rt.cpan.org, why is it even necessary to fork? And this doesn't seem to work, it breaks the existing interface in undocumented ways.

I think this is a really poor effort and best avoided. I suspect the same of the other modules by this author which seem to have a similar provenance.

Module-Rename (0.04)

Update: the module was changed: rt.cpan.org/Public/Bug/Display.html?i...

This would be a good module but it really needs updating. The "module-rename" script does not have any options to turn off what directories are altered, e.g. ".git".

I would suggest at least an "-i" interactive option and a "-d" for skipping directories for the script. Also the documented "-v" option does nothing: here is the exact output:

$ module-rename -v Lingua::JA::Gairaigo Lingua::JA::Gairaigo::Fuzzy
$

If you wanted to make this incredibly great, it would be just super if there was a way to override the "move" routine used. As an example, I changed in my personal hack of this module to use "git mv $old $new".

github.com/benkasminbullock/Module-Re...

This is a big help.

Getopt-Long-Descriptive (0.093)

Getopt::Long::Descriptive claims to be similar to Getopt::Long but with the addition of an automatically-generated usage message. However, for example, whereas with Getopt::Long, I can do something like

GetOptions ("verbose" => \my $verbose)

and have my program use -v as an option:

./script -v

with Getopt::Long::Descriptive, the short options don't occur unless I specify them. This may be a good thing or a bad thing, but either way it isn't the same thing as Getopt::Long, or even an extension of the same thing. Also, it is quite handy in short scripts to be able to send a reference like the \my $verbose above, which Getopt::Long::Descriptive doesn't support.

It would be great to have an automatic way to generate usage messages which was also compatible with Getopt::Long, but this isn't it. After evaluating this module I decided to stick with using Getopt::Long and here-documents for usage messages.

Roman (1.23) ****

This module converts between roman numerals (I, II, III, IV, V) and arabic numerals (1, 2, 3, 4, 5).

I tried and it worked for small numbers and the common cases. Unfortunately it seems to fail for some unusual roman numerals which are in wikipedia:

my $r1910 = 'MDCCCCX';

print arabic ($r1910), "\n";

Also, when it fails, it just gives an "undefined value" - may be it should print an error?

It says that it is restricted to ASCII symbols - that may have been true in 1995 but perhaps this can be updated for 2012?

Also, the namespace as "Roman" and the global exporting of the functions are a bit questionable.

Anyway if, like me, you are too lazy to code this yourself, it works for the common cases. I also think this would make a useful standalone script and would suggest adding a command-line roman/arabic converter using the module.

My simple test script is here: gist.github.com/3281070

Bootylicious (0.910102) *

(review refers to github version)

This barely functions. The example article it gives does not display the article text, the links to articles go to the wrong article. Generally it seems to be hopelessly broken.

Lingua-Syllable (0.03) *

An inspection of the code reveals exactly one function, which seems to be utter junk; on empty input it prints a warning and then continues to execute, with the empty input used as a parameter. This looks like code which has rarely actually been put to work.

Even worse, the one function it does contain is nothing but a wrapper for the Lingua::EN::Syllable module, but also using Lingua::Rhyme as a dependence. Why is it namespaced as Lingua::Syllable I do not know, but this seems to be pure namespace abuse on the part of the author, since it is only for English.

Lingua-Phoneme (0.011) *

Similar to Lingua::Rhyme, this seems to be very little more than clutter, taking up megabytes of CPAN space. It's also in the wrong namespace (should be Lingua::EN::..), and it forces the user into a particular choice of storage (a MySQL database).

I can't imagine how anyone could successfully use this module.

Poetry-Aum (1.1)

Unfinished Acme:: module cluttering CPAN.

The documentation claims "If you feel you need documentation for this module, please consult an experienced Perl Monger/Rabbi."

If you care to try it, you will find that nothing in the code works:

--------- INPUT:

use Poetry::Aum;
my $boo = Poetry::Aum->new ();

---------- OUTPUT:

Can't locate object method "new" via package "Poetry::Abstract::Entity" (perhaps you forgot to load "Poetry::Abstract::Entity"?) at /home/ben/software/install/lib/perl5/site_perl/5.14.1/Poetry/Aum.pm line 32.

------------

"If you feel CPAN needs this module, please consult an experienced Perl Monger/Rabbi".

Lingua-Rhyme (0.092) *

This code seems to be very difficult to use. First of all, it's in the wrong namespace, since it is only for English. Secondly, for whatever reason, it requires a MySQL database. The documentation only really describes how to make the MySQL database and says nothing about how the dictionary works or what algorithm might be used to decide a rhyme.

It's also rather a self-indulgent use of CPAN disc space (four megabytes of dictionaries are included in the distribution).

This module seems poorly-designed, self-indulgent and a waste of space.

Pod-POM-Web (1.17) ****

Of the Pod viewers I have tried, this one works the best by far. It found all the locally installed modules and displayed all the pod I tried it with. It displays encoded UTF-8 as well. The default display is not very nice though. It means clicking on some tiny boxes containing a plus, with the list of modules expanding up and down the left hand side, and the formatted pod on the right hand side is done in a hideous colour scheme.

Pod-Browser (1.0.1)

This doesn't find files on the local system so it's not much use for browsing local modules which aren't released to CPAN.

Pod-Server (1.12) ***

I installed and got running with the usual commands. It started working instantly without any hiccups, and it was clever enough to work out the name of the server and give a URL for it. Unlike Pod::Webserver I was able to access the generated pod pages from other computers. It was able to find all the pages on the local computer. It displays encoded UTF-8 correctly, and it has a nice design for the pages.

However, for some reason (maybe my misconfiguration) the top page only lists pod files from AE to DateTime::, with no "next page" visible, so it's necessary to type in the URL for other files. Also it only displays parts of some pod pages. For example, "DBI::FAQ" is visible down to "3.7 What databa" then it suddenly stops.

Pod-Webserver (3.05) **

I installed successfully and was able to start the pod webserver. The top page was visible from localhost, although not from other computers on the network. It correctly listed the installed pod files when viewed in Lynx. Each attempt to view the pages, however, resulted in a 404 error, so I was not able to view any Perl manual pages with this. The -H option didn't seem to work either.

The bug tracker on rt.cpan.org contains many bugs and patches from years ago. I assume this means the module is neglected or abandoned?

I was able to hack this into a workable thing by making a few small changes, but I can't recommend the module as it stands.

Morale (0.002)

It's a bit ironic that a "Perl module for managing individual and calculating group morale" ended at version 0.002, in 2001.

Perl-Critic (1.121)

The module has an impressive ability to parse Perl, but the policies which come as defaults with Perl::Critic are not all great. The first thing that bugged me was that each criticism contained a reference to a book which I don't own. I worked out how to stop it printing the book adverts with the following bizarre and obscure piece of configuration:

# Get rid of unwanted references to book.
verbose = 8

Then running it with various levels of severity, I encountered one annoyance after another. For example, a routine

sub xyz
{

my @stuff;

for (@_) {

if (something) { }

if (something else) { }

}

return @stuff;
}

offended the policy Subroutines::RequireArgUnpacking. Why rewrite a perfectly OK piece of code to placate this Critic?

Some of the policies had bugs. The policy InputOutput::RequireBriefOpen kept giving warnings about an unclosed file which clearly was closed. And why is the policy Perl::Critic::Policy::Miscellanea::RequireRcsKeywords a default, requiring the programmer to include strings from Fred Flintstone's version control system?

Although the test which says not to write "return undef;" is good, what is the point of the policy Subroutines::RequireFinalReturn which requires the programmer to write "return" at the end of a routine?

The regular expression policies RegularExpressions::RequireExtendedFormatting and RegularExpressions::RequireDotMatchAnything seem like dubious choices for defaults, since it is very possible that the programmer does not want "." to match "\n" or does not want extended formatting in every case.

RegularExpressions::ProhibitUnusualDelimiters told me not to use ! as a regex delimiter, but to use // and {}, both worse choices in some cases, and it cannot even be told to stop complaining about certain delimiters, but must be switched off completely in the .perlcriticrc file.

Perl::Critic would be great if it was a bit more minimalistic, and if some of the defaults were pruned a bit, but when your configuration file starts looking like this:

exclude = Subroutines::RequireFinalReturn TestingAndDebugging::RequireUseStrict Variables::RequireNegativeIndices BuiltinFunctions::RequireBlockGrep TestingAndDebugging::RequireUseWarnings InputOutput::RequireBriefOpen RegularExpressions::RequireExtendedFormatting ValuesAndExpressions::RequireQuotedHeredocTerminator ControlStructures::ProhibitCascadingIfElse Subroutines::ProhibitExcessComplexity ErrorHandling::RequireCarping RegularExpressions::ProhibitComplexRegexes ClassHierarchies::ProhibitExplicitISA Perl::Critic::Policy::Miscellanea::RequireRcsKeywords ClassHierarchies::ProhibitOneArgBless Subroutines::RequireArgUnpacking BuiltinFunctions::ProhibitStringyEval RegularExpressions::RequireDotMatchAnything RegularExpressions::RequireLineBoundaryMatching RegularExpressions::ProhibitUnusualDelimiters

you really wonder if you want to go on using it.

App-GitHub-create (0.0012) *

This no longer works, because the authentication scheme it uses was removed.

ack (2.00a01) *****

ack is a source-code search tool which offers recursive searching (going into directories), highlighting, and regular expression searches.

I have found this very helpful in searching through third-party source code, such as MetaCPAN source code, or even for finding stuff in header files in /usr/include.

I wish I had discovered this earlier.

Anchovy (0.01) *

Empty module, contains no code whatsoever.

WikiText (0.15) *

Module has been "coming soon" since 2008, but the submodules are empty stubs containing a package name and a 1; at the end.

On the bright side, the fact that the submodules contain only a 1; means that it passes all of its tests at cpan testers.

CPAN-Meta (2.120921) *****

I'm grateful to the author of this for writing clear documentation.

File-Compare (1.1001) *****

File::Compare provides a function for comparing two files to see if they are exactly the same or not.

It's a handy module for writing tests, e.g. this:

metacpan.org/source/BKB/Image-PNG-Fil...

Lingua-EN-Inflect-Number (1.1) *

This module is supposed to turn English nouns from plural to singular. However, the whole module is based on a mistake: it actually uses Lingua::EN::Inflect's method for turning a third person singular verb (he does, she likes, it eats) into a plain verb (I do, you like, they eat). The source code actually contains a comment "I don't know why this works, but it seems to." But unfortunately it doesn't; the most simple examples of irregular plurals are completely unhandled by this module:

input:

--------------

use warnings;
use strict;
use Test::More;
use Lingua::EN::Inflect::Number 'to_S';

my %words = qw/
bogus bogus
citrus citrus
menus menu
species species
flies fly
monkeys monkey
children child
women woman
mice mouse
/;

for my $word (sort keys %words) {

my $s = to_S ($word);

ok ($s eq $words{$word}, "$s == $words{$word}");
}
done_testing;

-------------

output:

--------------

ok 1 - bogus == bogus
not ok 2 - children == child
# Failed test 'children == child'
# at ./lingua-en-inflect-numbers.pl line 21.
ok 3 - citrus == citrus
ok 4 - fly == fly
not ok 5 - menus == menu
# Failed test 'menus == menu'
# at ./lingua-en-inflect-numbers.pl line 21.
not ok 6 - mice == mouse
# Failed test 'mice == mouse'
# at ./lingua-en-inflect-numbers.pl line 21.
ok 7 - monkey == monkey
ok 8 - species == species
not ok 9 - women == woman
# Failed test 'women == woman'
# at ./lingua-en-inflect-numbers.pl line 21.
1..9
# Looks like you failed 4 tests of 9.

-----------

This module is inadequate for turning English plural nouns to singular ones, and the two other things it does are already handled by Lingua::EN::Inflect.

Nums2Words (1.13) *****

Re Lester Hightower's self-review, please note this is not self-promotion, it is related to an ancient bug from at least three years ago which has never been fixed. See the following email, which I sent over two years ago, reporting the bug:

-------------------

MIME-Version: 1.0
Received: by 10.220.45.195 with HTTP; Sat, 11 Jul 2009 18:02:22 -0700 (PDT)
Date: Sun, 12 Jul 2009 10:02:22 +0900
Delivered-To: ....@gmail.com
Message-ID: <bea59c750907111802o248bac17w425fe4a819b932dc@mail.gmail.com>
Subject: CPAN ratings bug in search.cpan.org
From: Ben Bullock <....@gmail.com>
To: cpansearch@perl.org
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

Dear search.cpan.org maintainers,

There are two bugs regarding cpanratings.perl.org in search.cpan.org
which have been there for at least a year or so.

Bug #1: The number of reviews is wrong. The number of reviews given on
the search.cpan.org page shows the number of reviews where the
reviewer has given the module a star rating. For example,

search.cpan.org/dist/Net-Telnet/

says (3 Reviews) , yet there are actually four (one without a star
rating). This is repeated for many other cases.

Bug #2: If a reviewer writes a review, adds a star rating, then
deletes the star rating again, the star rating remains on
search.cpan.org. For example, see

cpanratings.perl.org/dist/Text-Levens...

Note there is only one review, with no stars, yet the above still
keeps the five stars that the reviewer added then removed. This is not
due to a slow update, since the stars were removed a year ago.

Ben Bullock

-----------------

Given that the unfortunate one-star rating is solely due to a bug, Mr. Hightower should be forgiven for self-rating 5 stars.

Since I've already reported the bug, maybe someone else could re-report it? Thanks.

Lingua-StopWords (0.09) *****

Lingua::StopWords provides lists of short words like "to" or "and" for several languages which should be neglected in searches. I installed Lingua::StopWords for use in a web log parser to remove uninteresting words from its list of search keywords. As far as I can see it works pretty well; some words it doesn't eliminate include "us" and "can", but since these could be "United States" or "Can of coca-cola" perhaps they are border cases.

The explanation of the module provides an example using "grep" of removing the stopwords from a list which I copied into my program. Although this is very simple, it would be preferable if this was provided as a method or procedure in the module.

Disclaimer: I have only used the English words part of this module. It provides lists for a lot of other languages but I didn't use them, so please consider this a review of the English-language parts only.

Number-ZipCode-JP (0.20120229)

review deleted.

Poem (0.01)

(Review deleted - this was a test of Unicode done on behalf of A.B.H.)

App-pmuninstall (0.28) *****

At last, a way to remove installed modules which works.

Dancer (1.3070) *****

I've never used Dancer but I'm planning to use it to host a blog containing ridiculous pictures of Celine Dion.

Lingua-EN-Numericalize (1.52)

Parts of the module work correctly. It also includes some very odd numbers, like eleventy-one, which seems to come from JRR Tolkein's books.

But, there are lots of bugs, and the code is almost like "Perl golf", and it is difficult to fix the bugs due to the coding style.

In case anyone is interested, the following repository contains an updated version of the module:

github.com/benkasminbullock/Lingua-EN...

Data-Stack (0.01)

It looks like a joke module to me. Everything here is already provided by Perl arrays. I imagine the author knows that? Surely nobody actually uses this.

autodie (2.10)

I read in a lot of places that "autodie" is something that can be used in the same fashion as "use strict" or "use warnings" to catch problems. I started putting it into a lot of places and automatically adding to the top of every script. However, for something which is intended to go into every Perl script, this module is very slow to load:

****** Item 1:

-------------
use warnings;
use strict;
print "hello world.\n";
-------------

$ time perl noautodie.pl
hello world.

real 0m0.007s
user 0m0.000s
sys 0m0.008s

****** Item 2:

--------------
use warnings;
use strict;
use autodie;
print "hello world.\n";
--------------

$ time perl autodie.pl
hello world.

real 0m0.084s
user 0m0.078s
sys 0m0.005s

I don't use this module any more, because of this performance problem.

(Someone wrote to me who was worried that I thought that autodie affected the time of "print" above. In case anyone is confused, please note that "autodie" doesn't affect the time of "print", as far as I know. You can remove the "print" and still get the same sort of time results. Check the autodie documentation at the link above the review for what the module does.)

Lingua-LO-Romanize (0.09) *****

I read the other review here and wondered why it was so harsh. Just out of interest when I saw the new version of this on CPAN, I took a look at this module by setting up a simple CGI script using it:

www.lemoda.net/lang/lingua-lo-romanize/

Just looking at the code, I wondered what the Moose was doing. It turned out the answer was "nothing". It took only a few minutes to remove everything to do with Moose from this module and give it a simple procedural interface:

www.lemoda.net/lang/lingua-lo-romaniz...

It still passes all the tests of the original (t/01-romanization.t):

www.lemoda.net/lang/lingua-lo-romaniz...

What is the function of Moose in this module? I think the other reviewer was right to be a bit angry about this unnecessary dependence. Although I wonder if that guy really needs to romanize Lao, or if it is just some kind of grandstanding using this module to attack Moose rather than write a review of this module itself. If you really need to romanize Lao and you hate Moose, it's pretty easy to get the functioning bits out of this module. No point in bashing this, and it's a bit cruel towards this module's author, who seems to be the only person in the world to have written free software to romanize Lao.

About the module itself, I am totally unqualified to pass comment. I noticed that when I tried the above CGI program on the Wikipedia page about the Lao language, there seem to be quite a few different forms of Lao romanization. If this is just one of them then maybe its name should reflect that, in case someone wants to also provide all the other forms of romanization.

Anyway I think the other review is a misuse of cpanratings so I will give this module five stars to compensate for the other silly review.

JSON (2.90)

This module parses the JSON format and puts it into Perl structures. I haven't used it the other way around so I don't know if it turns Perl structures into JSON or not, although it claims to.

Although it definitely works correctly, this module is difficult to use and the interface is over-complex and badly designed. It's also rather difficult to navigate the documentation. Before the maintainer changed the behaviour recently, the default behaviour was that it blew up with weird error messages like this:

Wide character in subroutine entry at ../lib/Blah.pm line 54

if it was sent "utf8" encoded Unicode text. Even after trying all kinds of different options, in the end it was easier just to re-encode the text using "encode_utf8" from the Encode module and send it. Even then I was still getting problems with "decode_json", for example

my $text = encode ('utf8', $contents->{response});

my $json = decode_json ($text);

caused an error

Cannot decode string with wide characters at /home/ben/software/install/lib/perl5/5.12.3/i386-freebsd/Encode.pm line 174.

but

my $text = encode ('utf8', $contents->{response});

my $json = from_json ($text);

did not produce this error, so I had to use "from_json" instead.

Why? Eventually I found out that one of these routines defaults to turning on the UTF-8 flag, and the other one defaults to turning it off. Then the error was bubbling up from another routine which sent the text to DBI. Why the module is written in this confusing way, I don't know, is it something to do with JSON::XS compatibility? Then the maintainer wrote a response review which demonstrates my point: to understand what this module is doing you need to spend a long time scrabbling through the documentation. Why on earth is it necessary to spend such a long time doing these things when JSON is such an absurdly simple format?

In the end, after seeing that maintainer's review, to save time:

search.cpan.org/dist/JSON-Parse/

It has two routines, one validator and one parser. Put UTF-8 flagged text in, get UTF-8 flagged text out. Put non-UTF-8 flagged text in, get non-UTF-8 flagged text out.

Math-Base36 (0.09) *****

I was about to do some work on improving my base 36 number reading routine when I had the idea to look on CPAN to see if there was any existing solution. I didn't expect to find anything but was surprised to find this. I'm using it to parse numbers created by JavaScript using "number.toString(36)" as a way of compressing message size. As far as I have used this, it works nicely, although my numbers only go from 0 to 36*36 - I haven't tested it beyond that.

(If you would like to make a comment about this review, please address it to me at bkb@cpan.org.)

HTTP-Date (6.02) *****

Effectively & correctly converts Unix epoch times to and from HTTP server style dates.

Cairo (1.062) *****

This is a full interface to the Cairo drawing library under Perl. It's very nicely done, and everything works just the same as if using the C library. The one criticism I have of this is that the documentation is not clearly organized, and a lot of it is just some kind of printout of function arguments which looks like gibberish to the untrained eye. I guess the authors didn't want to have to reproduce the documentation for the existing C library, or something? I already knew the C cairo library before using this, so it was easy for me to get going, but someone who looks at the documentation for the module is going to feel extremely confused and discouraged unless they already know what the library does. There are some good example scripts in the examples directory:

cpansearch.perl.org/src/TSCH/Cairo-1....

so start there rather than looking at the module documentation.

Re the other review, I had no problems at all installing this on FreeBSD. The problem I had installing it on Ubuntu Linux was the usual one where the OS installs the system libraries without the C header files (like "cairo.h"). In this case the Cairo library probably exists on almost any variety of Linux, but the header files might be missing. Just the following is enough to install on Ubuntu Linux:

sudo apt-get install libcairo2-dev
cpan Cairo

Here the libcairo2 is already installed but the -dev addition is necessary to get it to install header files. It's not the Cairo module's fault that Linux distributions don't include header files.

(If you want to respond to this review, my email is bkb@cpan.org.)

Net-OpenID-Consumer (1.15)

[review deleted]

WWW-RobotRules (6.01) *****

This module parses "robots.txt" and tells you if your url is allowed for your user agent.

(Contact me at bkb@cpan.org if you have a comment about this review.)

slice (1.2.8) *

A collection of ancient versions of modules not written by the alleged author of this module which clutters up CPAN search results. See also my review for cpanratings.perl.org/dist/lcwa, almost all of the comments there apply to this too.

Sorry author, I am sure that in 1998 this was a truly marvellous way to "Extract pre-defined slices from an ASCII file", although I have no idea why that task would require you to pull in modules like IO::Socket::INET, but in 2011 this is a blot on the landscape.
I suggest this whole thing should just be deleted.

(Contact me at bkb@cpan.org if you have a comment about this review.)

lcwa (1.0.0) *

Originally this seems to have been part of an application to do some kind of web crawling or something. I haven't even looked at that. The reason I am commenting is that a large part of this package is a collection of other people's modules, dated to when this package was released in 1997. As a result, a collection of extremely old versions of modules, which were not written by lcwa's author, have been sitting on CPAN unchanged since 1997. Maybe that would not be a problem if nobody knew about them, but in fact these extremely antiquated versions of modules turn up in the search results of search.cpan.org.

At the time of writing this review, an ancient version of WWW::RobotRules turns up as the second hit if you search for the term "robots.txt" on search.cpan.org:

search.cpan.org/search?query=robots.t...

See imgur.com/TmA5E for a screenshot.

Even worse, it's actually the sixth module on the list if you search for WWW::RobotRules.

When I searched for a module to read "robots.txt", I landed up at the version of WWW::RobotRules bundled in with this package. I spent quite a few minutes wondering why something like that had not been updated since 1997. I started to look for some more modern alternative, and I found my way to

search.cpan.org/~dmaki/WWW-RobotRules...

which comes below the above broken module but above the legitimate WWW::RobotRules. Now it says right at the top of this, "Unlike WWW::RobotRules (which is very cool),". However, since the version of WWW::RobotRules which I'd discovered before that was obviously not very cool, I was puzzled, so I went back to the search box of search.cpan.org and found my way back to the 2011 version of WWW:::RobotRules. This surely proves that there is something wrong with my method of searching search.cpan.org and what a fool I am, but I notice that this package even got some bug reports at rt.cpan.org which should have gone to the legitimate modules, so it seems there are other fools like me.

So this package is really a distraction and a nuisance. I don't know if it was necessary to bundle up third-party modules in a package in this way in 1997, but in 2011 it is a really bad practice, so my request is that this package should somehow be removed from CPAN, made invisible, have the ancient third party modules removed, or otherwise downgraded in the search.cpan.org search results.

(Contact me at bkb@cpan.org if you have a comment about this review.)

SVG (2.50) *****

This module is a writer for SVG (scalable vector graphics). It takes Perl structures containing the SVG data which you want to write, and turns them into SVG for you.

It seems to be complete and effective and will save you the work of turning your data from Perl form into XML tags.

One note is that the top level namespace "SVG" doesn't seem necessary to me, I think it should have been "Image::SVG". Note that the mime type for SVG is image/svg+xml.

It doesn't read SVG in.

The documentation is very complete. Some of the links in the documentation are dead.

(Contact me at bkb@cpan.org if you have a comment about this review.)

Algorithm-Munkres (0.08) *****

This is an implementation of a method of solving the assignment problem generalized to the case where there are different numbers of jobs to the number of assignees. This is linked to from the Wikipedia page on "Hungarian method".

The code seems to work OK, although I haven't carefully verified its correctness. It is very slow on very large datasets but pretty fast up to 100 x 100 matrices.

The interface is very simple and obvious, the documentation is a bit messed up, containing some dead links and odd formatting, but there is nothing here which needs extensive documentation anyway.

(Contact me at bkb@cpan.org if you have a comment about this review.)

SVG-Parser (1.03)

Does this module actually have anything to do with SVG? It looks like just a generic XML parser with the word "XML" crossed out and "SVG" inserted. The only thing the docs and examples contain are completely generic stuff about parsing XML.

Although SVG is formatted as XML, that is only a part of the story. Something which calls itself an SVG parser should be able to, for example, parse the "d" attribute of an SVG <path> element, see e.g.

www.w3.org/TR/SVG/paths.html#PathDataBNF

Otherwise what is it for?

IPC-Run3 (0.046)

I don't use this module any more because of unfixed bugs with UTF-8 handling.

CGI-Compress-Gzip (1.03) ****

CGI::Compress::Gzip offers a way to have your CGI output compressed into the gzip format using a drop-in replacement for CGI.pm. Although it works if you use it as described, unfortunately it isn't quite a drop-in replacement, since it assumes that you're using the object-oriented interface of CGI.pm rather than the procedural one. In other words,

use CGI::Compress::Gzip;
my $cgi = CGI::Compress::Gzip;
print $cgi->header;

words as you'd expect, but

use CGI::Compress::Gzip ':all';
print header;

creates an error message.

Also, in my opinion, this should be built in to CGI.pm itself in the first place rather than being an extension.

Another thing I would take issue with here is the documentation's claim that

"... if the script chooses HTML output, apply gzip compression on any content header for STDOUT."

This isn't actually what the module does, in fact it uses "select" to redirect the output of print; it doesn't affect STDOUT at all. For example, try the following example script:

#!/home/ben/software/install/bin/perl
use warnings;
use strict;
use CGI::Compress::Gzip;
use Template;

my $cgi = CGI::Compress::Gzip->new ();
print $cgi->header ();
print "bobobo\n";
my $tt = Template->new ({INCLUDE_PATH => '.'});
my %vars = (nice => 'guy');
$tt->process ("test.tmpl", \%vars, \*STDOUT, {binmode => ':utf8'})

or die ''. $tt->error ();

Make a text file called "test.tmpl" containing a line of text and then run without compression like this:

$ ./test-comp.cgi

Switch on compression like this:

$ HTTP_ACCEPT_ENCODING=gzip !$

You'll notice that the "Template" output isn't compressed via gzip, thus breaking everything.

It strikes me that it would be possible to replicate this module's functionality by opening an in-memory file handle:

open my $cgi_output, ">", \$string;

then selecting it:

select $cgi_output;

then running gzip on the string before printing it:

use IO::Compress::Gzip 'gzip' ;
gzip \$cgi_output, \$final_output;

print STDOUT $final_output;

There we are, this whole module in five lines of code. Too radical?

P.S. Sorry if this review isn't useful to you; perhaps you were looking for the Charlie Brown cartoons? Stay lucky, chums.

(Contact me at bkb@cpan.org if you have a comment about this review.)

Water (0.01) *****

Disregarding the advice of WC Fields, I often drink water. Now at last I can also download it from the internet, saving me the journey from my computer seat to the tap. Thanks very much to the creators of this module!

(Contact me at bkb@cpan.org if you have a comment about this review.)

ExtUtils-ParseXS (2.2206)

This module's documentation is pretty interesting. First of all, the only meaningful function which it documents is "process_xs", and yet no such function exists in the module. This is followed by a list of "named parameters" such as this:

C++
Adds extern "C" to the C code. Default is false.

Yeah, and actually looking at the source code we find:

# 'C++' => 0, # Doesn't seem to *do* anything...

Pity the fool who trusts this documentation.

Finally, the coup de grace is delivered by this:

s
I have no clue what this does. Strips function prefixes?

Fortunately or not, in fact "s" doesn't even exist in the module any more.

(Contact me at bkb@cpan.org if you have a comment about this review.)

WWW-YouTube-Download (0.26) *****

Worked for me. Documentation a little thin.

(Contact me at bkb@cpan.org if you have a comment about this review.)

Compress-Zlib (2.015)

(This is a comment on another review rather than an independent review of the module. Excuse me but there is no facility to add comments to reviews on this site and I think this is worth noting.)

Regarding the other review by Andy Grundman, the version of this module referenced in Andy's review (2.015) uses an XS module called Compress::Raw::Zlib rather than a pure Perl version.

(Contact me at bkb@cpan.org if you have a comment about this review.)

Lingua-EN-Inflect (1.893) ****

Lingua::EN::Inflect is a module to adjust single English words with indefinite articles (a/an) or plural and singular. There are various subroutines to turn words into their plurals or add articles. These seem to work well and handle all the usual exceptions like "child/children", "goose/geese", "a university/an upstart" as required, so this module may well be enough for people who want to output correctly formatted text as output from a computer program.

However, I got stuck when I wanted to use this to analyze input. The module does not have an interface to detect if a noun is plural or singular. This seemed very strange since the module's plural comparison functions must have that ability in order to do their work. Internally there is a routine which does this job, called _PL_check_plurals_N, but unfortunately it is not available in the public interface.

The naming and behaviour of the routines is a bit strange. For example "PL" for plural, but the same thing is also used to convert a verb from the third person singular form. For example PL("cat") gives you "cats" as output, but PL("cats") gives you "cat" as output. I don't see when that would be useful, it's a bad idea, and that is not related to plural: "I eat" and "we eat" are singular and plural forms of the same sentence, but the verb doesn't change.

As I said at the top this is probably good enough for the case when you are generating sentences via the computer and want to get your "a/an" and singular and plurals right. So basically it fulfils its purpose. However, that is about all it does, the name "Inflect" is a little pretentious considering this module's functionality.

(Contact me at bkb@cpan.org if you have a comment about this review.)

Lingua-Translate-Google (0.22) *****

Lingua::Translate::Google offers a "Google translate" (machine translation) backend to the existing "Lingua::Translate" module, which interacts with online translation services.

Just for fun, here is an example which translates the review just below this one on the cpanratings front page into English:

#!/home/ben/software/install/bin/perl
use warnings;
use strict;
use Encode qw/decode_utf8/;
use HTML::Entities;
use Lingua::Translate;
use LWP::Simple;
my $text = get 'cpanratings.perl.org/user/iakuf';
if ($text =~ /<blockquote class="review">(.+?)<\/blockquote>/s) {

$text = decode_entities ($1);

$text = decode_utf8 ($text);

Lingua::Translate::config (back_end => 'Google',format => 'text',);

my $xl8r = Lingua::Translate->new (src => 'zh-CN', dest => 'en');

print $xl8r->translate($text), "\n";
}

Lingua-EN-Syllable (0.251) ***

Lingua::EN::Syllable estimates the number of syllables in English words. In a test, it got about 87.6% right.

Here are the first few failure cases of the algorithm:

abandoned: 4 != 3
abased: 3 != 2
abasement: 4 != 3
abashed: 3 != 2
abatement: 4 != 3
abeyance: 2 != 3
aborigine: 4 != 5
abridged: 3 != 2
absorbed: 3 != 2
abstruseness: 4 != 3

Here the first number is the count given by Lingua::EN::Syllable and the second number is the correct number. As you can see, although it works moderately well, there are some obvious improvements which could be made, like not counting -ed at the end of words as a syllable unless there is a preceding t or d. However, it's likely that no purely algorithmic method could correctly count the syllables in words like "aborigine", so this is a fair stab. However, unfortunately, it doesn't have any way to return what it thinks the actual syllables are.

Coy (0.06) **

[This review and rating is of Lingua::EN::Hyphenate, which is a part of Coy. If you are interested in Coy, there is an interesting article here:

damian.conway.org/Resources/AmazonInt...

]

I found this module via Google and the following "mystery manual page":

manpages.ubuntu.com/manpages/dapper/m...

which doesn't seem to feature anywhere in the distribution.

Why? Because I am looking for a way to break English words into syllables. Now, first of all, note that an incredibly simplistic regex,

my @vowels = ($input =~ /([aeiou]+y?|y)/g);

gets you a 71.4% accurate syllable count. Compared to that, this module achieves a result of only 82.9% accuracy. I thought I could improve it, but a very quick look at the horrendously convoluted regular expressions used in the module and I gave up in despair.

Compare this to Lingua::EN::Syllable, which is about thirty lines of simple code (including two arrays of data), and gets a result of 87.6% accuracy. I am dumbstruck that such an amazing array of regular expressions and subroutines as I have seen in Lingua::EN::Hyphenate can give results as bad as this.

Module-Build (0.3800) **

Module::Build is a replacement for ExtUtils::MakeMaker for building CPAN modules.

Unless you already know exactly what you are doing before you start using it, Module::Build is very difficult to use, error-prone, and badly documented. For example, try the following experiment; delete the "package" line from your module. What happens? Here is the build script:

use Module::Build;
my $builder = Module::Build->new(

module_name => 'Fake::Module',
);
$builder->create_build_script();

---- end

Here is lib/Fake/Module.pm:

#package Fake::Module;
our $VERSION = 0.01;
1;

---- end

Here is the exact error message:

$ perl Build.PL
Can't determine distribution version, must supply either 'dist_version',
'dist_version_from', or 'module_name' parameter at /home/ben/software/install/lib/perl5/5.10.0/Module/Build/Base.pm line 1150.

Adding to this,

perldoc Module::Build

is no help at all telling me about any of these parameters.

This is just one example but very typical of Module::Build: meaningless error messages, and unhelpful documentation. I could pick several other examples, since I've had many, many frustrations like this dealing with Module::Build, but this was the one which prompted me to come here and write this review, since it actually happened (I accidentally deleted the "package" line from a long module, and spent some time trying to work out what on earth the above error message meant.)

Yes, it's my own fault for doing stupid things like accidentally deleting the "package" line from my module. But I don't want to spend all this time and agony learning the convolutions of Module::Build for what seems to be little gain.

To take yet another frustration from today (which is why I came back to rewrite this review), it seems I have not written a module abstract for a different module in the way that Module::Build requires, so it is complaining about "dist_abstract". And yet it does not document anywhere what the correct format for the module abstract is. I try searching on Google, and find in the docs for Module::Build::Functions

"Module::Build looks in the POD of the module from which it gets the distribution's version. If it finds a POD section marked "=head1 NAME", then it looks for the first line matching \s+-\s+(.+), and uses the captured text as the abstract."

OK, I write exactly what it says, like this:

=head1 NAME

Module - My Module

=cut

Does it work? No.

Then I try a whole bunch of other variations. Then I look at the source code to try to find what to do. Still I can't work it out. Again it's my own fault: somehow, some way, I should magically know what format Module::Build expects. But I don't.

Yes, I suppose I could study the source code even harder to work out what is going on. But if this really is meant to be the default way to build modules, is it too much to ask for it to be clearly documented, and have meaningful error messages, instead of sending people scrabbling around its source code or searching on Google?

There is some documentation of some of the parts in another module called "Module::Build::Functions", but unfortunately it's not accurate or complete.

(Contact me at bkb@cpan.org if you have a comment about this review.)

Module-Starter (1.54) ***

(This is a review of the "module-starter" script)

"module-starter" is a script for creating the necessary directories and files when beginning writing a new Perl module. There are nice functions for creating a build script, with a choice of ExtUtils::MakeMaker, Module::Install, or Module::Build, and also functions for creating a manifest and an ignore list for files which should not be put under version control.

It would be incredibly useful if it just did the basic stuff to create a module, but unfortunately this actually does too many things. For example, it puts a message saying "The Great New <module>" into the Pod, and then it also writes a test which checks that the programmer has removed this message. It sounds like a joke, but it isn't. I'd rather, instead of creating all this busy-work, they had kept it simple and not written the text which I then have to remove.

It also insists on including email and free software licence information, with a limited choice of licences and no way to turn this off or alter it. That would be useful if every module was going to CPAN, but my guess is that most modules actually never get released publicly. Also it insists on putting lots of links to rt.cpan.org, cpanratings, and so on and so on. If these were options they would be great, but as unswitchoffable defaults they are not so great.

Not having an obvious way to turn all these bits and pieces off, module-starter becomes a little exasperating. My verdict: using it creates about as much work as it saves. I recommend against it.

It might be worth remarking that the Module::Starter module which this script is based on also has a facility to add one's own starter modules using it as a framework. I don't know if any exist but it might be an easier way to create something than starting again from scratch.

(Note: the "4/14 found this helpful" votes which appear on this review refer to a completely different review I wrote a long time ago.)

Text-LevenshteinXS (0.03) **

This module doesn't handle UTF-8 encoded strings correctly. It only works on ASCII.

(I tried to put an example here but cpanratings turned all of the bytes into html entities. Please replace "some unicode" and "some other unicode" with two strings in UTF-8 separated by one character difference.)

#!/home/ben/software/install/bin/perl
use warnings;
use strict;
use utf8;
use Text::LevenshteinXS qw/distance/;
print distance ("<some unicode>", "<some other unicode>"), " ", distance ("saru", "sagru"), "\n";

which should print 1 1 but prints 3 1

See also

rt.cpan.org/Public/Bug/Display.html?i...

HTML-Lint (2.06) **

I wanted to check some cruddy old HTML pages for errors, so I started looking on CPAN. HTML::Lint was the second thing I came upon, after one other thing which looked very difficult to install.

It did a few useful things, like catching closing tags without an equivalent opening, or informing about img tags with no height, width, or alt text. But this module has a big problem if your web page contains any UTF-8 encoded Unicode characters. If you use its "parse_file" method, not only does it insist that you have to use HTML entities:

Invalid character \xC2 should be written as &Acirc;
Invalid character \xA9 should be written as &copy;

but even worse it doesn't take any notice of your encoding anyway, and it tells you to use entities for each byte, which is wrong and will result in a broken web page. If you read the text in yourself as UTF-8 and send it to this module via its "parse" method, things get even worse since it doesn't have any way of coping with these inputs. When I tried using "parse" on a Unicode-encoded string, I got streams of errors like this:

Use of uninitialized value $val in substitution (s///) at /home/ben/software/install/lib/perl5/site_perl/5.10.0/HTML/Lint/Error.pm line 112.

I tried fiddling with the three error switches provided, but it turned out that switching off the entity part also switches off the other parts which were useful to me. I guess one could just send the output of this module through 'grep -v "Invalid character"' to remove these bogus errors.

Looking at the issue tracker for the module

code.google.com/p/html-lint/issues/list

it seems like the above problems have been reported already.

FreeBSD-i386-Ptrace (0.03) *****

The "ptrace" system call provides a way to control a running process, such as catching system calls. This module is specific to the FreeBSD operating system on the Intel 386 processor.

I came to this module after trying fairly unsuccessfully to work out how to call the poorly-documented FreeBSD ptrace. I was looking for an example of ptrace in C. As it happens, Dan Kogai's Perl module was the best thing available for information on these functions. I ended up unwrapping Dan's Perl example into C.

Besides that, it's also a very useful module in itself, if you need to access ptrace in FreeBSD.

JavaScript (1.16) *****

This module provides an interface between Perl and the spidermonkey JavaScript engine from Mozilla. I installed this because I could not get the latest version of JE to work on my computer. The module works very well to the small extent I have used it so far.

The documentation of the module is fairly sparse but it seems to be enough.

The installation of the module itself was fairly painless. However, the installation of the spidermonkey library is not so painless, and unfortunately the "system" version of spidermonkey which comes with some free OSes seems usually to be broken, so it is necessary to self-install the library. The reviewer who complained about the installation problems surely must have had problems with that.

The following page was pretty helpful in installing spidermonkey:

dt.in.th/2008-03-03.spidermonkey-linu...

EDIT:

Sorry, but the above blog page is gone now, unfortunately. But I have something which may be useful on my website:

www.lemoda.net/javascript/spidermonke...

File-ShareDir (1.03)

(Review removed, I no longer use this module.)

Religion-Islam-Quran (1.0)

This module offers various kinds of searches through the Koran/Quran.

The module contains the full text of the Koran in several languages including Arabic, installed into the Perl library space, which may not be the best choice of locations.

I've read the documentation and I've read the source code, and browsed through all the files, and I haven't seen anything resembling any kind of propaganda in it. It's no different from the modules like "Religion::Bible::*".

One criticism of the module is that it seems like the author is not too clear on Perl's powerful encoding abilities since converting the windows-1256 text version of the Koran (QuranArabic.txt) into the Unicode file also offered (QuranArabicUnicode.txt) is a doddle:

#!/home/ben/software/install/bin/perl
use Modern::Perl;
open my $input, "<:encoding(windows-1256)", "QuranArabic.txt" or die $!;
binmode STDOUT, "utf8";
while (my $line = <$input>) {

for my $char (split //, $line) {

my $num = ord($char);

if ($num > 0x80) {

print "&#$num;";

} else {

print $char;

}

}
}
close $input or die $!;

I just about squeezed this into a one-liner (90 characters long):

perl -MEncode -ne'for$i(split//,decode("cp1256",$_)){$n=ord$i;$i="&#$n;"if$n>128
;print$i}'

This exactly reproduces the file QuranArabicUnicode.txt in the distribution, so why not save five megabytes?

Crypt-DH-GMP (0.00005) *****

This is a drop-in replacement for Crypt::DH which eliminates a somewhat troublesome dependency. It can be used to replace a Crypt::DH dependency in a third-party module.

common-sense (2.0) *

The documentation for the module makes completely false claims. It says "save a tree AND a kitten".

Not only did my tree get a disease and die, but one of my kittens ran away and I haven't seen him again.

I blame this Perl module.

Net-Whois-IP (1.04) *

This is a recursive whois which queries successive servers.

It's flaky, and badly documented, and it even discards its own results (??).

Better to just use backticks: `whois 127.0.0.1`.

Win32-Process-List (0.09) ****

This module gives a list of processes and PID numbers on Windows. It is an interface to an XS module which calls native Windows routines. The module works on Windows and also Cygwin.

I downloaded this module in order to write a script which would detect a running Emacs process. As an experiment, I used it to make a script to kill off all instances of Google Chrome.

See www.lemoda.net/perl/win-ps-list/win-p... for the code.

This worked OK to zap all the Chrome processes. However, I noticed that:

* the actual list of processes is created by "new". "GetProcesses" returns an array that was created by "new". This could catch you out if you have a script running for some time and the process list changes, because GetProcesses will return the list of processes at the time "new" was called.

* The functions described in the documentation don't have the documented behaviour. For example, GetProcessPID returns a hash, not a scalar as described. This function doesn't seem to work, though, so the SYNOPSIS program doesn't run anyway.

* It may be easier to just access the undocumented XS function ListProcesses. In the above example,

my %list = %{ Win32::Process::List::ListProcesses(undef) };

gets the same result.

So, although it works well enough, the module doesn't have proper documentation and the documented functions in it all seem to be "fake-o".

Net-OpenID-JanRain (1.1.1) *

This module's installation scripts don't work (notice it fails tests on every system).

Looking at the test reports I thought maybe I could get it to work by installing some of the missing dependencies, like CGI::Session, by hand.

However, this wasn't such an easy task as I'd imagined.

I've also installed Net::OpenID::Consumer and got it to work after a short struggle, so I suggest using that instead.

Win32-OLE (0.1709) *****

Win32::OLE is a Perl module for interacting with Microsoft's OLE system for automating application programs. It can be used to control Office programs like Excel, Word, and PowerPoint from a Perl script. The entire object model of the Microsoft applications is available, so it is possible to almost completely replace VBA by Perl. (The parts you can't easily replace are things like forms.) I use this module daily and have had very few problems with it. The integration of the Microsoft objects into Perl object form has been done very well.

There are some books on how to use Perl with Microsoft applications, but I've never looked at them since it is easy to translate the online VBA documentation into Perl.

Another big plus is the ActiveState mailing lists where one can get very well-informed help for these modules.

* Pitfalls for the unwary

However, people who are thinking about using this module should know that the transition between the Microsoft and Perl worlds is not always entirely smooth. A bug which often catches me out is sending what I thought was a number (for example to specify an Excel sheet or column) to a Microsoft object and having an error thrown back at me, because what I thought was a number was actually a string:

my $text = "sheet12";
if ($text =~ /sheet(\d+)/) {

my $sheet = $1;

my $value = $Excel->Sheets($sheet)->cells(1,2)->Value();

# Crashes!
}

(The error here is that $sheet is a string not a number to OLE.)

Another source of trouble is Excel's date fields, which I solved thanks to advice found on Perlmonks.

Yet another problem is file names; sometimes / works, and sometimes it doesn't, and you have to

$filename =~ s:/:\\:g;

to get Windows applications to accept file names. For example, Excel will happily open a file /like/this but when you try to use the SaveAs method, it will only accept a file name \like\this.

* Comparison with other modules

For purposes of comparison, accessing Excel via Win32::OLE seems to be about five times faster than using the ParseExcel module on CPAN. On the other hand, you can't really use Excel via OLE non-interactively, so if you need to process Excel files in the background, ParseExcel is a better bet.

Net-Telnet (3.03)

[Review deleted pending update - sorry]

CGI.pm (3.44) ***

Although CGI.pm is a "core module" included with the distribution of Perl, it has an ill-thought out, cluttered interface. Unfortunately, this interface can't be changed, since so much is built on top of it.

The documentation deserves special mention for being unreadable and unhelpful. Example: one of the basic functions of CGI.pm is to read from STDIN. Where is this even mentioned in the documentation? Absolutely nowhere. Instead, if you search for the words "STDIN" or "standard input", you'll find a lot of obscure claptrap, and not even one mention of the vitally important fact that using this module means that it reads standard input to EOF. Another reviewer mentions that the idea is to write gibberish documentation and then put the real documentation in a for-sale book in order to make money. That's a very cynical comment but it may even be true in this case.

Added to the problems of dealing with the horrible instructions are the inclusion of a set of fancy and yet irritating HTML generation routines. This is a design mistake. Dealing with the CGI is a completely different task from HTML generation, and HTML generation routines have no business in a CGI module.

The maintenance of the module is also questionable. The source code is a hodge-podge of patches and it is filled with "dead" comments which no longer apply to the code. Copyright notices seem to be out of date.

However, despite the negativity expressed above, which was created by the frustration of dealing with this module's documentation as a beginner Perl programmer, I want to qualify this review by saying that the code DOES ACTUALLY WORK, unlike a lot of the imitator CGI modules on CPAN.

Modern-Perl (1.03) *****

Modern::Perl is a module which you can "use" to save writing "use strict;" and "use warnings;" and "use 5010;" When I first saw it I thought "what a stupid idea, I'll never use that." After typing "use strict;" and so on for about twenty times after that, I realised that it was actually a pretty good idea. I installed it today and I will probably be using it for everything from now on.

Net-MacMap (0.01) *

This module maps MAC addresses (ethernet hardware addresses) to the manufacturer (called the "vendor" for some reason).

This contains a list of MAC vendors hard-coded into its source code. Since the module hasn't been updated since 2003, and the list of MAC vendors is updated every day, I suggest using Net::MAC::Vendor, which pulls info directly from the website, instead of this.

Net-MAC-Vendor (1.18) ****

Net::MAC::Vendor provides a way to get information about the vendor from the MAC (Media Access Control) number which is associated with Ethernet hardware. It's handy for jobs like working from a router's arp table to what the hardware actually is (e.g. Nintendos or something for which it's hard to find what the IP address is).

The "lookup" part of the module works correctly although not quite as described (reported as rt.cpan.org bug #44963) - the vendor is the first part of the array and the address part is the rest. However, why does the module even bother returning the postal address? Unless we are planning some kind of mass mail shot to ethernet hardware vendors, the only information anyone is really likely to want is the vendor. Why not just provide that, and people who actually need the postal address for some reason could go to the IEEE web site.

Also, the dependence on the DBM::Deep module for caching seems unnecessary to me. The information which needs to be stored and read is an extremely simple fixed format which could be read into a hash and appended to a text file without the need for any dependencies, particularly one as complex as this.

WWW-Scraper-ISBN-ISBNdb_Driver (0.07) *****

This is a backend for WWW::Scraper::ISBN, a method of retrieving information about books via their international standard book number (ISBN) from the internet. This particular module obtains this information from the "isbndb.com" web site. In order to use the module, each user needs to obtain a string called a "key" from isbndb.com.

Once you have obtained your key, you can test whether it works with the test scripts provided with this module. For example, in Cygwin, I installed this module, then set a variable "ISBNDB_ACCESS_KEY" like this:

$ ISBNDB_ACCESS_KEY="ABCDEFG"

$ export ISBNDB_ACCESS_KEY

and went to the test directory of the module, "/home/bkb/.cpan/build/WWW-Scraper-ISBN-ISBNdb_Driver-0.07/t" and ran the following test:

$ perl -T 01-isbndb.t

The module worked correctly as described to retrieve information about books based on their ISBNs from the isbndb.com web site.

However, it would be nice if the module's default behaviour didn't require "no warnings;". Also the module currently has a bug that it doesn't check its return value from Business::ISBN->new() and so it just crashes on a bad ISBN value with a weird error message instead of failing cleanly.

[This review was altered on 4 April 2009 to reflect changes to this driver module.]

Net-Interface (1.011) **

Net::Interface promises to be a version of the Unix command "ifconfig" for use by Perl. It sounds like a good idea but my experience of the module so far has not been very good. The documentation does not make clear what systems the module is able to run on. It compiled on Linux but not on Cygwin so possibly Cygwin is not supported. However, although it compiled on Linux many of the functions failed to run. Although "ifconfig -a" returns the MAC address of my ethernet interface, this module failed to get it: using the ->info() method, very strangely it says that my mac address of eth0 is "[". Also, the function "hwaddress" failed to run with an error message. What surprised me the most was to get a "Usage: " message from the module even though I was running it from a script.

The documentation is not good. It starts off by telling you it is a "Perl extension" which is something hopefully we already knew. The synopsis doesn't offer an example but a list of imports, which is not much use. The body of the documentation is a mish-mash, for example there are sudden random comments in the middle of the documentation saying "NO LONGER SUPPORTED". I'm sorry but it's hard to read something as disorganized as this.

The interface seems frankly horrible: here is a quote from the documentation:

"->new(); has multiple calling invocations.
This method will refresh the data for an existing interface OR it can modify and existing interface OR it can create a new interface or alias."

I know "there's more than one way to do it" but I think it's virtually an abuse of conventions to stuff a function to refresh data for an interface into a function called "new".

This would be a good module if it ran on all platforms and worked properly, but since it's easy enough to just call ifconfig/ipconfig via "system" or backticks, this module doesn't seem very useful to me.

Test-Warn (0.11) *****

Test::Warn provides a way to test the warnings output by your Perl program.

The syntax of the tests seems odd to me, but it was clear enough what to do from the examples provided. Test::Warn seems fairly comprehensive since it also coped with warnings emitted by carp/croak.

The best thing about it is that it is fully integrated with Test::More, so you don't have to do any extra fiddling to get this to work beyond installing it.

Just as a side note, and regarding the review I wrote of Test::Pod::Coverage, this is yet another module which fails to install because of failed pod tests. If you are on Cygwin and this fails to install, remove t/pod.t and all will be well.

Win32-Codepage (1.00) *****

This module returns the default code page for your Windows system. I only needed the function "get_encoding" from this module. For my particular problem it returned the code page encoding correctly.

Test-Pod-Coverage (1.08)

Message to all Perl module authors: could you please disable Pod coverage tests when you distribute a module through CPAN?

First of all, as other reviewers note, the above module is difficult to set up and run, and so including these tests in your distribution will make your module fail to install on some people's systems. This will reduce the number of people who can use your module.

Second of all, this module is only useful for module authors, to check that your documentation matches the actual module. Your module's end-users do not need to run these tests.

Win32-WebBrowser (1.02) ****

Win32::WebBrowser starts the default web browser on Windows.

I tested it by changing around the default browser and pointing the module both at files on my system and the world-wide web, and I'm glad to say that it works exactly as stated, but it would be nice if the module was integrated slightly better into the Perl ecology.

At the moment it is set up to fail "make" and "make test" if $^0 is not set to 'MSWin32', hence the failed tests on Linux systems. Just for the sake of the CPAN testers, the make script should be set up better to detect the OS and do something more sensible than just going kaboom.

Also, despite the way it is set up, the module installed and ran perfectly on Cygwin after I'd commented out parts of the installation scripts (most of t/01load.t and lines 14-22 of Makefile.PL).

re-engine-TRE (0.04) *

Tre (www.laurikari.net/tre/) is a regular expression library which extends standard regular expressions with approximate string matching. The re::engine::TRE module links the Tre regex engine into Perl as a substitute for the usual Perl matcher.

The module has very little written description of what it does, in particular there is nothing about how to use the approximate regexes. After much trial and error with no success, I went to the tests of this module, but still couldn't find anything which told me how Tre's syntax was implemented.

Unfortunately Tre itself is barely documented. The website's documentation consists of a grammar with not even a single example. However, it has lots of tests, so I took some example regexs from tre's "tests/retest.c" file, which look something like this:

test_comp("\\<(foobar){~}\\>", REG_EXTENDED, 0);
test_exec("zfoobarz", 0, REG_OK, 0, 8, 0, 8, END);
test_exec("boing zfoobarz goobar woop", 0, REG_OK, 15, 21, 15, 21, END);

and tried putting them into this module.

No luck!

Either the module hasn't implemented Tre's special regexes, or the author hasn't written any tests or documentation which use them. Just one line of example documentation, or even just a line in the test script, would have made a big difference to the useability of this module.

JavaScript-Minifier (1.05) *****

This is one of several or even many JavaScript reducers on CPAN. This module works correctly to reduce the size of JavaScript files.

JavaScript-Packer (0.04)

Review withdrawn.

JE (0.032) *****

JE is a JavaScript engine written in Perl. It parses and executes JavaScript, and allows communication between the JavaScript and Perl. Impressively, it can parse big chunks of JavaScript without error and execute the parsed code correctly. This gives one way to run unit tests of JavaScript code from a Perl script without having to fiddle around with a browser, which is quite handy if you need to program something complex in JavaScript.

On the negative side, as the documentation states, it is fairly slow. JE doesn't know anything about things like document.getElementByID and other such DOM stuff, so it won't work on most of the JavaScript on the world-wide web. I don't know if there are plans to make it work with parsed documents in the future, but the author has also written an HTML::DOM module.

The documentation is not particularly nice but it is good enough to get you started writing stuff quickly. The interface is also fairly easy to understand. Parts of the module are clearly unfinished, with error messages sometimes popping up from obscure line numbers inside the source code (this only happened when parsing incorrect JavaScript though).

[Note to the other reviewer: Regarding the name "JE", my guess is that due to the many sub-modules, the author decided to pick a very short name in order not to have to type such incredibly long things as JavaScript::Engine::Object::Error::ReferenceError. It also goes by the alternative name of "JavaScript::Engine" if you prefer.]

Template-Multilingual (1.00) ***

This module is for templates in multiple human languages, so the user can get a different output from a template depending on which language they select.

I spotted this module a day or two ago after having spent a little time doing exactly this job, making some HTML pages for different human languages. I had been using the plain template toolkit and found it worked pretty well.

I looked at this module wondering what advantages it offered. However, having read the documentation and source code, and written a test script, I don't think there is very much this module does which the plain template toolkit itself can't. Using the example from the documentation, the template toolkit can do much the same thing, if we just throw a variable "lang" into it:
[%- IF lang == "en" -%]
Hello!
[%- ELSIF lang == "fr" -%]
Bonjour!
[%- END %]
The advantage of the template toolkit is that it has the [% %] syntax, which I much prefer to the HTML-tag-like format of Template::Multilingual. Things which look just like HTML tags could be confusing stuck in the middle of real HTML. Template toolkit syntax stands out from HTML, and you can look at an unprocessed file in a browser, without the browser deleting the tags. Template::Multilingual's pseudo-HTML tags will just disappear.

The only thing which Template::Multilingual seems to offer above the template toolkit is the ability to parse strings like "en_US" and find default values like "en" when US English isn't available. That isn't particularly useful for me, but it may be for some.

String (1.5) *

This module makes a close approximation of the JavaScript "String" object for Perl, offering functions like String.toUpperCase as a replacement for "uc":

my $x = new String("Perl");
$x->toUpperCase;

instead of

$x = "Perl";
uc $x;

Perhaps it's meant to be useful for a JavaScript programmer coming to Perl for the first time, or as part of a backend for some kind of automated JavaScript to Perl convertor, but the documentation doesn't mention why Perl needs this.

Lingua-Romana-Perligata (0.50)

Very whimsical.

(I'm giving this FIVE STARS because of the STUPID BUG in search.cpan.org whereby it doesn't update the star rating.)

Text-Tree (1.0) *****

This module produces an ASCII graphics tree from inputs.

The functionality is fairly basic but it does what it claims.

Bugs exist in multi-line (\n) handling.

Tree-Visualize (0.01) *

The author states "I am releasing this to CPAN largely as a means of self-motivation".

With no progress since November 2004, and a version number of 0.01, perhaps this means of self-motivation has been unsuccessful.

Note that many of the source code files are empty.

CGI-Mungo (1.1)

Why put both CGI::Mungo and Mungo (top level namespace)?

Lingua-JA-Kana (0.05)

This is a module for converting between three forms of Japanese writing, hiragana, katakana, and romaji. It is definitely a better bet than Lingua::JA::Romaji.

It functions correctly but is fairly basic. For example, the handling of ん is inadequate, and generally the module has no options to control the type of romanization performed.

[Review revised 9 Feb. 2009 since bugs mentioned in previous review have now been fixed.]

[Review revised again in June 2011 since module now handles full/half width katakana. Star rating removed but will probably persist in search.cpan.org due to a bug which I reported, years ago, but still isn't fixed.]

Contact me at bkb@cpan.org to comment on this review.

Moose (0.87)

Review deleted. Sorry to leave this here, but cpanratings has no function to delete a review.

[P.S. My reason for deletion: the original review referred to an installation failure on Cygwin which, the last time I tried the module, was repaired. I haven't tried using the module since I successfully test-installed it on Cygwin, and I don't currently have any plans to do so, so I'd be acting in bad faith to write a review of it. Hence, this review is deleted.]

Module-Install (0.91) ***

The basic notion of Module::Install is to have an easier way to install your module with all kinds of things done automatically. This is a good idea, but it does so many things automatically that it's more than a little annoying. For example: if you happen to have a file called "test.pl" lying around in the directory, it will try to incorporate that into your module's set of tests, without asking you, even though it may be something you don't even want in the distribution. Or you may have some alternative or obsolete .pm files you actually don't want in your distribution, but it will try to bundle them all up and write tests for them.

Another annoying thing is its behaviour with regards to the MANIFEST file: it "kitchen sinks" the MANIFEST with every bit of cruft and every rotten old file that it can find in the directory tree. Perhaps I'm untidy or disorganized but I'm tired of having to continually fight against this module adding unwanted files and tests all over the place. This module is much too clever, and it should be stripped down to do no more than the user expects.

<Added to review August 2009>:

Here is a typical example of the irritating behaviour I described above:

[ben@mikan] My-Stupid-Module 519 $ make manifest
/home/ben/software/install/bin/perl "-Iinc" "-MExtUtils::Manifest=mkmanifest" -e

mkmanifest
Added to MANIFEST: boo
Added to MANIFEST: bugs/bug_list.xml
Added to MANIFEST: inc/Module/Install/Scripts.pm
Added to MANIFEST: My::Stupid::Module-0.01.tar.gz

Doubly irritatingly, it tells me I should edit a file called "MANIFEST.SKIP" in order to tell it not to do all this.

No! It should never have added those files without asking in the first place. I don't want to tidy my development directory, and I don't want to have to write a stupid MANIFEST.SKIP file either.

<added to review 19 Feb./modified August 2009>

Another annoying thing is that it can break compatibility with other modules. As the other modules get updated, Module::Install stays the same inside your directory, and on repeated occasions an install failed because of an incompatible old version of Module::Install.

Frankly, it's annoying. The only reason I'm still using this instead of ExtUtils::MakeMaker is because of File::ShareDir.

Mail-IMAPClient (3.18) *****

The module behaved largely as I expected and performed correctly and robustly to search, retrieve, and delete mail from the server under a variety of requirements. At the time of writing, this seems to be the best documented and most useful module for dealing with IMAP on CPAN.

With reference to Florian Knell's review about the speed of the module, I believe this is a server-side issue and not the module's fault at all.

Netscape-Bookmarks (1.95) ***

Hmm, there are two versions of this module floating around the internet, one on CPAN and one on SourceForge, causing users some confusion.

Both work with Firefox but some of the attribute fields of the bookmarks from recent versions of Firefox are missing.

It would be nice if

a) the author updated it to work with the bookmarks of recent versions of Firefox.
b) there weren't two versions.

Lingua-EN-Phoneme (0.01)

A good idea but the module seems misnamed. This isn't a general phoneme module for the English language but a way of getting phonemes out of CMUDict. I'd call it Lingua::En::CMUDict or something similar.

NetxAP (0.02) *

The only reason I am writing this review is because "search.cpan.org" gives Net::IMAP as its third result upon a search for "imap".

Let me save you five minutes: this module doesn't pass its own tests, and hasn't been updated for ten years. I suggest you use Mail::IMAPClient, which unfortunately search.cpan.org relegates to the second page of search results.

IMAP-Client (0.13) ***

I stumbled upon this while looking for some kind of IMAP module, because unfortunately "search.cpan.org" doesn't have any kind of popularity feature to rate its search results.

Upon a brief trial of this module, there doesn't seem to be anything particularly wrong with it, but if you are wondering what IMAP module to use, Mail::IMAPClient is a much better bet than this one. It has better documentation and more functionality.

XML-Parser (2.36) ***

I sometimes need to parse the horrible format known as XML. What to do? The obvious solution in Perl seems to be XML::Parser.

However, XML::Parser has been a miserable experience. Yes, it works, but it is not nice. The problem is that the nature of the callback structure forces you either to use untidy global variables, or jam some foreign object into the parser object itself in order to keep your data somewhere as you parse the XML. In other words, there is no sensible place in XML::Parser to keep your data as you parse your XML file. It's as if it was designed only to parse the data but not ever do anything else with it.

This leads to the problem I've had with this, that every time I use XML::Parser, and want to do something slightly different, I end up having to copy and paste the entire parsing code, even if I am reading exactly the same file. It's very difficult to bundle everything up into a module to read the file and so I tend to end up with hundreds of similar and yet annoyingly incompatible parsers for exactly the same data.

However, today I came to CPAN ratings, looked at the other ratings for XML::Parser, and found recommendation for XML::SAX. I went and looked at the documentation, and found the solution to my problem is to use a closure:

"The only way currently with XML::Parser to safely maintain state is to use a closure:

my $state = MyState->new();

$parser->setHandlers(Start => sub { handle_start($state, @_) });"

That's useful to know.

libwww-perl (5.820) *****

I really like this set of modules, because they save me so much time. The functions do what I think they're going to do, and the documentation always heads me in the right direction. Unlike the horrific CGI.pm, even when I was a complete beginner at Perl I was able to use these modules without severe stress, which is one of the big reasons I like them.

I'm sure these modules have their limitations but if I need to stretch the boundaries of what these can do, I'd expect to have to fiddle with source code and write my own modules. I'd much rather have a simple thing to make straightforward jobs easier than a complicated thing which I can't use to "just get it done".

Mail-Mbox-MessageParser (1.5000) *

How hard can it be to write a parser for the mbox format? The whole thing is just a concatenation of files separated by a blank line and /^From /. So why is it that writers of "fast and simple mbox parsers" like this can get things so wrong? For something which claims to be simple the installation alone requires downloads of a huge variety of C programs. I had more luck just writing my own mbox parser.

MIME-tools (5.427) ****

The module seems to work very well, although there are parts of it I don't yet understand, but the documentation is an incomprehensible mixture of annoying quips and patchy information. In the end I had to resort to reading and altering the source code to work out what the module was doing. Any documentation, for any module, needs clear pieces of sample code so that programmers can work out how to use the module. Lame quips and vague statements are not helpful.

Mail-Box (2.084) *

This module is not only difficult to understand, but also doesn't seem to work, and for added fun it takes an age to install. A winning combination! All I wanted to do was to parse an mbox file. So I downloaded and installed this. Too bad, it won't install. So, after also trying another couple of CPAN modules, I ended up writing my own parser. Guess what? Between the time I spent struggling with this module's near-incomprehensible, miserable cross-linked documentation and waiting for it to miserably fail its tests, I think I spent more time on this module than I did on writing my own mbox parser.

Mail-POP3Client (2.18) *****

This module worked "out of the box" for my task without any problems or complications. Documentation seems complete and accurate.

Text-Levenshtein (0.07)

[Review deleted]

warnings-unused (0.04)

Review deleted due to module compilation failure.

Text-Banner (1.00) ***

It doesn't install using cpan, and the directory structure seems messed up, so you have to download it and install it "by hand" (make / make install doesn't work either) from the tar file instead.

Once you do, you get something which is like the Unix "banner" command, but with a lot of "creeping features" and object-oriented guff syntax, so first of all you have to create your object with "new", then "set" your banner and then "fill" it and then "get" it - clearly a case of object oriented programming going too far. Why not just have one simple single routine called "banner" which prints a reasonable default banner using # or X or something?

Fortunately it doesn't use Moose, but even so honestly I'm not sure what the point of the features and the object orientation is. And the default behaviour is plain stupid, it prints out the banner using ones and zeros: seriously this is its output (sorry if fixed width gets messed up):

0000000 0000000 0000000 0000000 0000000 0000000 0000000 0011100
0011110 0100001 0000000 0011110 0111110 0001100 0111110 0011100
0100001 0100001 0000000 0100001 0100001 0010010 0100001 0011100
0100001 0111111 0000000 0100000 0100001 0100001 0100001 0001000
0100001 0100001 0000000 0100000 0111110 0111111 0111110 0000000
0100001 0100001 0000000 0100001 0100010 0100001 0100000 0011100
0011110 0100001 0000000 0011110 0100001 0100001 0100000 0011100

The other annoying thing about the module is that it stores its data as some kind of crushed binary, which superficially looks clever but actually will surely be a pain if you want to do something other than use the banner characters the author suggests.

You could use this if you're desperate to have a Perl solution, but I'd recommend using the C banner program from Cedar Solutions which comes with Cygwin instead, or if you want lots of font options you might also like "figlet". The banner which comes with Linux is not much use because it prints too big and vertically instead of horizontally.

W3C-LinkChecker (4.5) ***

W3C::LinkChecker is the WWW consortium's own link checker (it looks at links in HTML pages and tries to check whether they are OK or not.)

It works but the results are horribly ugly and it's buggy, printing out uninitialized variable warnings to STDERR as it runs.

On the HTML setting the results are really silly and bossy messages ("This link is broken. Fix it NOW!") in a horrible colour scheme of red, yellow and grey.

Other problems: it doesn't seem to have any way to stop repeating the same messages over and over again when links to the same page appear on more than one checked page. In fact I ran it using its "--recursive" option on a set of pages which all contain links to the w3 consortium's CSS/HTML checkers, and for every single page it checked, it printed out exactly the same messages, over and over again, about robots.txt.

As far as checking links goes, it worked to some extent but it doesn't have features which I'd expect in a link checker. Xenu's link sleuth probably works better than this.

Games-Battleship (0.05) *

This game is very boring.

Badger (0.01)

According to the copyright notice, version 0.01 has been in development since 1996. Given another twelve years hopefully we'll get to version 0.02.

Perhaps this is why Mr T pities the fool that attempts to builds a production system based on Badger version 0.01!

Text-SimpleTable (0.05)

Hmm, what's wrong with Text::ASCIITable?

This looks like reinventing the wheel.

Template-Toolkit (2.20) *****

The template toolkit enables you to automate repetitive tasks in your Perl script without having to use "here documents" and long strings of text within the script itself. This aids maintenance of the Perl script and the text, since they can be edited separately.

The template toolkit is fairly well-thought-out and has been in use for long enough by enough people that bugs are very few. It is also very comprehensive, and has fairly good and complete instructions. But I have no idea why the author offers the documentation in such a variety of colour schemes. Some kind of whimsy?

One negative point I have is with the "extra language" one has to use for the toolkit. If I was going to make my own toolkit (I don't need to because this already exists), I would not use a separate syntax but just keep the usual Perl syntax inside the command bits [% %].

Data-Validation (0.2.52)

Looking at the source code for

Data::Validation::Constraints::Email

we find

use Moose;
use Email::Valid;

then there are three lines of code which call Email::Valid. I'm not sure it even uses Moose, perhaps that is just there to look trendy.

Similarly there is a number validator which calls up a routine from Scalar::Util, and so on.

I have to ask what's the point of making modules like this, which just call other modules.

For the postcode part of the module, it doesn't mention that this is UK postcodes (not Canadian postcodes or something) module. How about taking over the maintenance of the existing but abandoned module Geo::Postcode instead of making another one?

Text-ASCIITable-TW (v0.02)

Since the module doesn't have any documentation to speak of, perhaps it's worth pointing out that it's intended to make Text::ASCIITable useable with Taiwanese (Traditional Chinese) characters.

It would make a whole lot more sense to write an ascii table module using the Unicode::EastAsianWidth module, which has the facility to detect wide characters from any east Asian language, including Korean, Japanese, and simplified Chinese.

Even more sense would be made if the author managed to convince the Text::ASCIITable author to incorporate that into the original module.

DateTime-Locale (0.43)

[This is a review of DateTime::Locale::ja, but some of the contents refer to the DateTime::Locale module too.]

This module is inadequate. It makes no effort to conform to the standard Japanese practice regarding dates (era-based years) and thus is of little practical use. It's a kind of "paint-by-numbers" methodology of creating a locale module which doesn't really reflect local usage.

It would make more sense to have modules like this written by people who speak the languages in question. Further, it would make more sense not to package all the DateTime::Locale modules together, so that someone who just wants to install one language's locale doesn't end up having to download a hundred or so date localization modules.

Still, one must be very careful not to anger the Perl gods who write all these crappy modules.

WWW-CPANRatings-RSS (0.0304)

Review deleted.

Test-Simple (0.92)

Review deleted.

Regexp-Wildcards (1.01)

This is a nice module & looks to be very helpful in making user interfaces for people who don't understand regular expressions.

Regexp-Common (2.122)

This is a useful module. However, it would be a much better module if all the cruft, like regular expressions to match tv urls, was removed from it. Unless tv urls are much more common than I had thought?

Acme-EpicFail (0.02) *

Hm, I thought it was lame. First of all it failed its tests on Cygwin. Second of all the only thing it does is either print "EPIC FAIL!" or "EPIC MEGA FAIL!". I was expecting some more spectacular forms of failure.

Pod-Simple (3.16) ***

[This is a review of Pod::Simple::HTML.]

The HTML created by the module is incredibly ugly. For some reason I'm probably not qualified to understand it makes every single heading into a link back to the top of the page, so there are these horrible blue links everywhere, on every title. I'm sure it's possible to turn these ugly and unnecessary links somehow using some obscure, undocumented option, but why would that be the default?

I started using this because the evil pod2html script supplied with Perl actually started deleting chunks of the pod documentation I was writing, without warning (stuff which passed through podchecker cleanly, by the way).

But the output of Pod::Simple::HTML is just too horrible for me to want to continue with it.

No wonder so many people have written pod to HTML convertors when the existing ones seem so broken - notice that CPAN is littered with alternative versions of modules which do the same task, and yet none of them actually do a particularly good job.

Further the documentation is screwed and just awful, and look at the other review which says "The docs could use some work, but it's still in development, so I'd expect them to improve in future releases."

Written five years ago, and "the docs" could still "use some work" in August 2008.

(Addendum: 24 May 2011)

First of all apologies for whatever mistake I made about the CPAN HTML. I don't have a record of what it was I said but I seem to have erased that from the review, so sorry if I've confused people with that too.

I don't usually use POD to make web pages, but I recently had another chance to look at this module when preparing a web page based on POD which I'd edited from something in the Perl distribution:

www.lemoda.net/xs/perlxstut/

The output of Pod::Simple::HTML is just a total mess, and this time I did take the trouble to look through the source code and confirm that there was no sensible way to make it do obvious things like removing the leading whitespace or turning off the links to the top of the page. Such things really don't exist in the code. Here's the script which I use to build that web page from the POD (the POD for the above page is downloadable from a link at the bottom):

use Pod::Simple::HTML;
my $file = 'perlxstutdigest.pod';
my $out = 'perlxstutdigest.html';
my $p = Pod::Simple::HTML->new ();
my $output;
$p->html_h_level(2);
$p->index (1);
$p->output_string (\$output);
$p->parse_file ($file);
$output =~ s/href=.*?top of document'//g;
$output =~ s~.*<!-- start doc -->~~sgm;
$output =~ s~<!-- end doc -->.*~~sgm;
$output =~ s~<pre~<pre class='perl-code'~sgm;
$output =~ s~(<pre[^>]+>)\s+~$1~g;
while ($output =~ s!(<pre.*?\n)\h{4}(.*?</pre>)!$1BUGGERS$2!sgm) {
# print ".\n";
}
$output =~ s/BUGGERS//g;
open my $outfh, ">:encoding(utf8)", $out;
print $outfh $output;
close $outfh;

All of that is just cleanup for things which the module either should not have put there in the first place or should have cleaned up itself.

Pod-HtmlEasy (1.0102)

The module is OK if you use it to read and write from standard input/output as it says halfway through the documentation. However, it seems quite flaky and buggy if you actually try to use the module as a module. The podhtmleasy.pl script supplied with the module doesn't work and it keeps whining

"All options must be paired with values"

Similarly if you try to write your own script using it.

The HTML output looks like CPAN's which is a big benefit compared to the ugly one produced by POD::Simple::HTML.

But either the documentation is broken, or the module is broken, in a way that a couple of test scripts should have shown up, so I can't give it more than three stars. Write proper tests and fix the documentation.

DateTime-Calendar-Japanese-Era (0.08001) ****

The module works as stated but with a few quibbles. Firstly it has enough dependencies to keep the computer busy for about ten minutes just to install it, including all those good old Albanian dates. Secondly the documentation doesn't tell you what's in the data structure, so you've got to go and look at the source code. Thirdly, the data is not in an ideal format - the kanji names come out as UTF-8 but not decoded, so you either have to use "Encode::decode_utf8" to get the data into utf8 for actual printing, or turn off utf8 printing on your output stream.

Fourthly, the id names of the eras are OK for a unique ID but it would be nice to have either a kana or romaji version of the name without the numbers which are added for uniqueness, like SHOUWA2, otherwise the user has to strip off the 2's.

I'd also quibble with the decision to use File::ShareDir to store the data - since there is little possibility of not having to load all the data, why is it necessary to add another layer of complexity to the module?

The module is perfectly functional as it stands but there are enough quibbles that I won't give it five stars: ★★★★☆

Disclaimer: I have no idea about the reliability of the dates used in the module.

Convert-EastAsianWidth (1.02)

Zonked review since no longer relevant.

Unicode-EastAsianWidth (1.30) *****

If you have to deal with East Asian (Japanese, Chinese, etc.) encodings, you'll have to deal with full and half width characters. This module provides character properties for use in a \p (property) inside a regular expression which match full and half width, making it easier to distinguish between the two cases.

Unlike the similar function in Unicode::Japanese, this module passed the spot checks I applied to it with flying colours.

A useful module which saves other people time and functions correctly.

Five stars: ★★★★★

Flickr-Simple (0.01) *

I found this module from a post on the Flickr API group on Flickr (flickr.com/groups/api/) and immediately joined the module's mailing list. When I tried to use the module, I found that the documentation was inadequate (there is not enough information to actually use the code). I pointed this out on the mailing list for the module, and the author told me to read the source code.

Frankly it's easier to just replicate the functionality of the module by writing my own source code - why release a module you don't intend to document or maintain?

Since it comes with inadequate documentation, it is unuseable, and because it's remained at version 0.01 for a year, I'll give this module only one star. ☆☆★☆☆

Unicode-Unihan (0.04)

As it stands, this module is not very useful.

If you have a copy of Unihan.txt, you can do the following to get the same results as the example given in this module, assuming $c contains the character you want to look up:

system ("grep U\\+".sprintf ("%X",ord ($c))." Unihan.txt | grep Mandarin");

So, since it's possible to replace the only function of this module with "grep", I'm not really sure what the point of the module is. Perhaps Unicode::Unihan has a speed advantage. But that is the only advantage that I can imagine.

Also, the AUTOLOAD-based interface is not very practical. If I want to look up the kMandarin key of the Unihan database, I have to access it via a named method like

$uh->Mandarin ($c)

that means that it's hard (messy) to access an arbitrary lookup key at run time, and unless I want to run around eval'ing, the lookup keys have to be hard-coded at compile time. That makes it hard to use this module as a backend for a user accessing a dictionary front end. It would be much cleaner to allow access via something like

$uh->lookup ('Mandarin', $c)

Using AUTOLOAD to create a method to look up the key is an example of someone doing something which is "too clever" and not actually useful.

Another deficiency of the module is that it doesn't have a method to grab all the keys associated with a particular character, like

my $hash_ref_containing_everything = $uh->all_info ($c)

That seems like an obvious functionality, and it's the first thing I'd implement if I was making this module. And, we should be able to go from a value, like the Mandarin pronunciation above, to the characters, so I can go

my @list_of_chars = $uh->lookup_values ('Mandarin', 'TUAN');

not just from a specific character to its specific value of one key.

Finally, for the sake of convenience it would be nice if there was a way to get a list of all the keys in the database other than going and looking at Unicode's web page.

Image-ExifTool (7.60) *****

I've used this module for a variety of images from a variety of cameras and found it to be complete and well documented. I tried the other EXIF modules on CPAN too and I'm pretty sure this is the one to use.

Incidentally to the review, it may be interesting to note that the source code is the only example I've seen of extensive (comprehensive?) use of Perl's prototype system in a CPAN module.

Image-EXIF (1.00.3) **

It's not complete enough to be useful, and the interface is not documented. I suggest using Image::ExifTool instead.

String-Approx (3.26) **

This module seems to work to some extent, but it has a fair share of problems. It's written using a C extension, and it doesn't work with Perl's utf8, so lengths from "aindex" and "aslice" come out in bytes even when it's fed a correctly encoded UTF-8 string.

The documentation is fairly lousy, and does not bother to carefully describe what it means by "approximate match". It was only by looking at the test code that I could understand what it meant

The calling conventions for these routines are also counterintuitive The routine "aslice" refuses to return a list in list context. Instead, if it's called in list context, it returns a reference to an array, and if it's called in scalar context, it returns a list, which is then converted to a number because of the scalar context. I don't know what the author could possibly have been thinking when he designed that.

*Be warned* also about version 2.7 of this module. cpanratings doesn't seem to allow me to add different comments for two versions of the same module, so I'll put comments here. First, the code is dangerous - it calls "die" if there is an input error instead of just returning to the calling routine. Also the source code is almost unreadable, with variable names which are one or two letters long, and worst of all the methodology is insane - it creates regular expression of length O(n!), where n is length of the original string we're trying to match, using a list of every possible combination of "nearly matching" strings. Note that this insanity is from an author who wrote a book on "Mastering Algorithms with Perl". It works with UTF-8, because it only uses regular expressions, but it's an utter mess. I can't recommend either version 3.26 or version 2.7.

Three stars for version 3.26: ★☆★☆★
One star for version 2.7: ★☆☆☆☆

Flickr-API (1.01) ****

I've used this to make a few toy flickr applications, like a search function. Although it works, the module is very basic, without much Flickr-specific functionality. I had to write my own module for adding tags to photos, authentication, making the link to the photo, etc.

Lingua-Flags (0.05) ***

A cute idea, make little flags for each country for use in web pages.

It failed its tests for some reason, but I installed it after that anyway, because the problem seemed to be badly-written tests rather than bad code.

Suggestions for improvement:

1. It would make sense to use something like File::ShareDir (part of Module::Install) to store the data in rather than having all the data in the module. At the moment the module is over 100,000 bytes of mostly data.

2. It would be preferable to have SVG or other vector versions of the flags rather than gifs, if possible.

Three stars: ★☆★☆★

Flickr-Upload (1.32) *****

I was sick of jUploadr*, I couldn't be bothered to keep switching on Windows to use the "real" Flickr Uploadr, and uploading bunches of photos via the web interface was too fiddly. So I installed this module and wrote a script, which is about twenty lines. In a few minutes I had a working command-line photo uploader for Flickr.

[P.S. Note that there is actually an upload script in the distribution, so you don't need to make your own].

* jUploadr grabs core memory to store each photo in full, so if one drags and drops twenty or so large photos onto jUploadr on a normal powered computer, the computer virtually comes to a halt for one hour.

String-Diff (0.04) ****

Basically a wrapper for Algorithm::Diff, this module is fairly handy, and the documentation is better than Algorithm::Diff's is (which isn't saying much, since drinking a pint of salty sea water would probably be more fun than reading Algorithm::Diff's documentation).

The module works as advertised, but its application for most people won't be much more than just an example of Algorithm::Diff.

Four stars: ★★☆★★

String-String (0.01) *

A completely pointless module, it consists of exactly one line of code, and a hundred lines of documentation. I don't know why anyone would need to download a CPAN module for the sake of saving writing one line of code.

IWL (0.61) *

The parts of IWL which I've looked at seem to all be duplicates of existing modules. It has IWL::String module which duplicates URI::Escape, and IWL::JSON which presumably duplicates all the other JSON modules, and a hundred-line-plus IWL::Text module which just concatenates text either at the end or the beginning of a string. Literally its entire functionality is

$x .= $y

and

$x = $y . $x;

That's all IWL::Text does, and yet it's 116 lines long.

Why does CPAN need yet another set of duplications of existing modules? A waste of time and disc space.

@Guido: Thanks for your opinion. In the light of your comment, I reexamined the module. I don't see any reason to change what I wrote above. I suggest you write your own favourable review independently of mine so that people can get a balanced view, rather than just reacting to what I wrote.

String-Buffer (0.05) *

I have absolutely no idea what the point of this module is.

Perl already has strings, and all this module does is add some functions which duplicate basic functions in Perl, with probably more typing than the original Perl.

String-Strip (1.01)

Re the comments of the other two reviewers of the module:

#!/usr/local/bin/perl -wl
use strict;
use String::Strip;
my $test = " \ta b-c def g; * ";
my $test2 = $test;
print "<",$test,">";
StripSpace ($test);
print "<",$test,">";
print "$test2";
StripLTSpace ($test2);
print "<",$test,">";

prints
$ ./stringstriptest.pl
< a b-c def g; * >
<ab-cdefg;*>

a b-c def g; *
<ab-cdefg;*>

So it doesn't seem to work as advertised, but it doesn't seem to delete hyphens either.

Acme-Monta (0.01) ***

Presentation method of popular Japanese TV host "Mino Monta" in HTML. Click the text and the colour changes from black so you can read the hidden words.

Lingua-JA-Romaji (0.03) *

CPAN's "first come, first served" system means that sometimes an inadequate module grabs pole position, and Lingua::JA::Romaji is a prime example. The module seems never to have gone beyond the testing stage, since it contains some quite amazing bugs. For example, びょ, which should be romanized as "byo", comes out as "bo", and dasshutsu is changed into だっしゅっつ (note the extra っ). Another bug is that the module stops converting as soon as it hits anything it doesn't expect, so even if you put a punctuation character, like a comma, in the string to be changed to kana, the module will fail to proceed beyond it. Further, the romanization isn't even consistent to any particular system, with まっちゃ coming out as "maccha" instead of "matcha" (Hepburn) or "mattya" (Kunrei).

Internally, the module is a mess, using EUC-JP for its encoding, so if you want to use it with modern Perl you'll have to spend time messing around with "encode" and "decode", and it hasn't been updated since 2002.

In conclusion, this is not a robust or useful module.

Encode (2.29) ****

This is a review of "Encode::Guess", not "Encode" (blame cpanratings for this).

Encode::Guess is a Perl module which guesses the kind of character encoding of some data. It's mostly intended for distinguishing between the dozens of confusing encoding systems used in Japanese and Chinese and other such languages, and doesn't make many promises about being able to guess the encodings of European character sets.

My main interest is in Japanese encodings, and I used Encode::Guess
successfully to decode some files written in either CP932 (Shift JIS) or UTF-8.

Although the module worked, and did its job well, I still have to say that this implementation is counterintuitive. First of all the documentation is very bizarre. The very first thing it tells you, the example in the "Synopsis" section of the documentation, to use Encode::decode ("Guess",...) is horrible and you will be miserable if you try to use this. I guess most people will do the same thing as me and start with the example in the synopsis before they read the whole of the documentation. It was only after struggling with the decode ("Guess",...) method that I came across another way to access this module's functions, buried down in the middle of the documentation. This is to make a $decoder object using Encode::Guess->guess.

The interface is idiosyncratic, but this worked very much more smoothly than using decode ("Guess",...). For example, decode ("Guess",...) just dies if it encounters an error, and it seems to be quite buggy. The object method doesn't die on any kind of error, but just returns a string (instead of a ref) if it fails. [So you have to check whether you got a string or a ref back to find out whether it failed, which is odd, but never mind.] Using the decoder turned out to accomplish what I had wanted to do very well.

As a suggestion for improvement, one thing I think a lot of people would find useful is a way to ask the module to guess the encoding of a file without my having to read the file, catch errors, close the file again, and then decode the contents. A simple routine which takes a file name as an argument and returns a string to send to "encoding", as in

my $XYZ = tell_me_the_file_encoding_of($weirdfile);
die "Unknown encoding" if !$XYZ;
open my $input, "<:encoding($XYZ)", $weirdfile or die $!;

would be handy.

In general this is a highly useful module but I can't give five stars since the interface and documentation are fairly iffy, and the decode ("Guess" thing even seems quite buggy.

DateTime-Format-Japanese (0.04000) *****

This review has been deleted. The reason for deleting the review is that I have no desire to download this module yet again and find out whether the comments I made about the module still apply.

Unicode-Japanese (0.46) ****

The XS version of the module works and installs without problems on Cygwin, and it seems to have a huge number of encodings available. But, for modern-day Perls, since 5.8.1, it isn't clear that these are necessary any more, because Encode does this work.

The module seems to work around byte-encodings, and I was surprised to get a non-UTF-8-flagged string of UTF-8 from the routines the first time I tried it.

I wrote a simple testing program for the module whose core function is like this:

sub testit
{

my ($text, $method) = @_;

my $uj = Unicode::Japanese->new($text);

my $ujout = eval ("\$uj->$method");

my $ujtext = $ujout->getu;

my $ujlen = $ujout->strlen;

print "Method $method on input '$text' gives output '$ujtext' with length $ujlen";
}

my $str = 'バカデンジャラス';
print Unicode::Japanese->new($str)->getu;
testit ($str,'z2h');
my $halfwidth = Unicode::Japanese->new($str)->z2h->getu;
testit ($halfwidth, 'kata2hira');
testit ($str, 'kata2hira');

In short order, I found two things which I thought strange. First of all, kata2hira doesn't convert halfwidth katakana into hiragana. Second, the strlen function is a nice idea, but it gives the halfwidth katakana a width of two instead of one. So these functions aren't incredibly useful. I recommend using Unicode::EastAsianWidth instead.

Another thing which surprised me is that it mixed up shift-JIS and CP932 and called the latter Shift_JIS. It probably would be better just to tell people to use the name "CP932" instead of "Shift-JIS", since it's just possible people could actually want "real" Shift-JIS instead of CP932.

Four and a half stars: ★★★★½

Data-Validate-Japanese (0.01001)

[Review deleted]

Lingua-JA-Regular (0.09) *

Perl programmers who have to deal with Japanese might need something to transform half-width and full-width characters, or irregular kanji, and might come across this module in a search for "zenkaku" or "hankaku".

Unfortunately, though, this module is not useable as it stands. First of all it doesn't install correctly. If you're thinking of installing it, note that this module uses Dan Kogai's Jcode.pm, and the reason it fails "make test" is because it doesn't mention that dependency. If you install Jcode before Lingua::JA::Regular, it will pass all its tests and install correctly.

Note also that the module is based on the EUC-JP encoding. In particular the functions for dealing with CP932 just convert the CP932 characters into ASCII forms rather than the corresponding Unicode symbol.

This module also has functions for dealing with fullwidth spaces, but these are obsoleted if you use Perl's internal encoding, since \s matches fullwidth spaces (0x3000, the things called "IDEOGRAPHIC SPACE" in the Unicode documentation). There may have been justification for using EUC-JP when the original version of the module came out, since version 0.01 of this module came out before Perl 5.8.1, but if you have to deal with a lot of Japanese codes nowadays you'd be better off switching to utf8.

The documentation is also minimal, unfortunately, and it doesn't have any facility to set the character set required except by looking at $ENV{HTTP_USER_AGENT}, which is weird. I'd recommend not using this module unless it's greatly updated.

One star: ★☆☆☆☆

Pod-Html (1.09_04) ***

This is a review of pod2html, not "Pod-Html".

It's fairly annoying.

The most annoying part of pod2html is that the error messages don't have line numbers but paragraph numbers - even though pod is a line-based format. So it's next to impossible to work out where the errors are. To work around this, you can run the module through podchecker, but podchecker doesn't give you all the error messages, for example the ones about links not being found.

Other annoying behaviours include turning a link to something into "the ... manpage". Note that search.cpan.org itself doesn't seem to use the module either.

Three stars: ★★★☆☆

DateTime-Calendar-Japanese (0.06001)

This module seems incredibly bloated, requiring huge numbers of other, unrelated, modules and libraries to be downloaded and installed. For example, it requires a download of date formatting for Albanian to be installed, even though Albanian has nothing to do with either Japanese or Chinese. Although certainly the date calculations are complex, I think it's very hard to justify the number of downloads this module requires which don't have anything to do with Japanese or Chinese dates.

File-Mork (0.3) ***

This is much better written and more useable than Mozilla::Mork, but its documentation and interface don't add much value to the original Zawinski script, mork.pl, which it was copied from, and it has some fairly glaring bugs. Like Mozilla::Mork, it's quite hard to see what the author is trying to achieve which mork.pl doesn't. If you use this module, you'll probably end up having to alter the source code anyway, so I'd recommend starting from the original Zawinski script instead:

www.jwz.org/hacks/mork.pl

But ... note that the Zawinski Mork parser also has some bugs.

Three stars: ★☆★☆★

Mozilla-Mork (0.01) **

Basically a stripped-down version of Jamie Zawinski's mork.pl script, it's hard to see the point of this module. In particular the documentation is unhelpful and the Perl code does very little extra beyond what mork.pl does. Its interface is downright annoying, with lots of verbose messages even when you set $verbose to zero, printing of whitespace to STDOUT while parsing, etc., and it seems to be fairly buggy.

If you need to parse Mork, you'd probably be better off adapting Jamie Zawinski's mork.pl instead of this:

www.jwz.org/hacks/mork.pl

HTML-TableExtract (2.10)

Useful, but has flaws.

This module is very handy for getting the entries out of tables quickly. However it has some flaws. For example it's not possible to get the attributes of the <td> and other tags which form the table, so if you need to extract only the elements which have a certain name or class, you'll be stuck with this.

There is a way around the problem but it's complicated.

The other big problem with this module is that it's broken on Cygwin and Windows.

ShiftJIS-CP932-Correct (0.05)

I found this module when I was processing a bunch of Microsoft Word files and getting errors of the form "shiftjis \x87 does not map to unicode". I quickly installed this module, put it into my program, ran the program again, and got rid of the errors, in a couple of minutes.

However, in retrospect I should have just used the CP932 encoding rather than using Shift-JIS.

Lingua-JA-Numbers (0.04) *****

This is a module for converting between numbers represented as arabic numerals (0..9) and Japanese-style kanji numerals. It can also turn a number in arabic numerals into its Japanese pronunciation.

The module works as described and is clearly documented. It is able to convert numbers in either kanji or kana, and it can cope with "big" numbers which overflow Perl's integer representation by using strings.

Smart-Comments (v1.0.3)

Review deleted. [I'd rather add print statements actually.]

Business-ISBN (2.05) *****

This module works as described in the documentation, is easy to use, is well documented, and does its job correctly.

WWW-Search-ISBNDB (0.3) *

First of all, the documentation of this module has a lot of problems. The example at the top doesn't work, it has ' in the wrong places, the "native_query" method used for searching isn't documented, and when you do get it to run it just prints out HASH(0x10239485) type of things instead of meaningful results.

Secondly, the module doesn't seem to work properly - the results I got were nonsense, and I couldn't see what I was supposed to do from the documentation. I wanted to search by ISBN but it didn't make it clear how to do that.

In the end it was much easier to write the scraper "by hand" using LWP::Simple and the excellent API documentation of ISBNdb.com than using this module, so my advice is to forget it.

WWW-Scraper-ISBN (0.25)

Review deleted, since the [negative] comments I made don't apply to the most recent version.

WWW-Scraper-ISBN-Pearson_Driver (0.10) *

This module doesn't seem to function at all any more. It returned failure on every one of 27 ISBNs I tried.

WWW-Scraper-ISBN-LOC_Driver (0.22) *

This module doesn't seem to work at all. Without investigating the internals, it completely failed to get any results on 27 common ISBNs (John Grisham novels etc.) so it's a fair bet that this is no longer functional.

Lingua-EN-Numbers (1.01) *****

This module converts between numbers written as words, as in "Twenty-two", and arabic numerals, as in "22". It seems to work satisfactorily.