Reviews by Michael R. Davis

cpanratings
 

RSS

Lazy-Lockfile (1.20) *****

Bottom line the best lock file system I could find on the CPAN. I did a bunch of research. I need an easy one that just works. So, call me Lazy.

- Supports custom lock file name.

- Supports clean start after kill.

- Supports clean up on out of scope.

- Supports updates via RPM without walking on itself (unlike Sys::RunAlone which locks <DATA>)

Documentation Issues - new constructor only supports hash reference style arguments ->new({}) it took trial and error to find the bug in my code.

Easy enough

use Lazy::Lockfile;
my $lockfile = Lazy::Lockfile->new("/tmp/$process-$realm.lock") || exit;

Geo-Google-StaticMaps (0.1) ****

Works well. Thanks for putting it together.

Update 2014-01-27: Google deactivated the V1 API. I have taken all of the good concepts of this package and ported them to a new API at Geo::Google::StaticMaps::V2. Unfortunately, it is not API compatible.

WWW-eNom (v1.2.8) ***

I wish the API were better documented in the POD. Even though it would be a copy and paste exercise it would help make the API more user friendly.

It might be nice if the return were an object instead of a hash as well.

It also might be nice to add a value added method SetHost which does a GetHosts+SetHosts in the backend.

i.e. SetHost(HostName=>"myhost", RecordType=>"TXT", Address=>"My String"); (pull GetHosts; modify return; push SetHosts);

The supported commands can be found in WWW::eNom::Role::Commands and the eNom documentation can be found at www.enom.com/resellers/APICommandCata...

Otherwise it works.

Email-MIME (1.82) *****

Version: 1.863

I spent an hour trying to get MIME::Parser(5.427) to just extract an attachment to disk. I never could figure out the API. But, in 2 minutes I was able to get it all done with Email::MIME(1.863).

use Path::Class qw{file dir};
use Email::MIME;
my $message = do {local $/; <>};
my $email = Email::MIME->new($message);

foreach my $part ($email->parts) {

if ($part->filename) {

my $file=file($part->filename); #isa Path::Class::File object

my $fh=$file->openw;

print $fh $part->body;

}
}

Thanks for the nice Interface!

Text-CSV-Slurp (1.0) *****

I did an evaluation of Text-CSV-Hashify-0.04 vs. Text-CSV-Slurp-1.0. And Text-CSV-Slurp beat Text-CSV-Hashify hands down. The only capability the Text-CSV-Hashify package provides that Text-CSV-Slurp does not is the hash capability but that's a simple map anyway.

my %hoh=map {$_->{"key"}=>$_} @aoh;

The only knick I'm going to give the interface is the "load" method use as a constructor and the use of Test:Most which is a not normal test package. Try is_deeply from Test::More instead of cmp_deeply from Test::Most.

Text-CSV-Hashify (0.04) *

I did an evaluation of Text-CSV-Hashify-0.04 vs. Text-CSV-Slurp-1.0. And Text-CSV-Slurp beet Text-CSV-Hashify hands down. The only capability this package provides that Text-CSV-Slurp does not is the hash capability but that's a simple map anyway.

my %hoh=map {$_->{"key"}=>$_} @aoh;

Documentation is wrong in a few places and I opened two bug reports.

Parallel-ForkManager (1.02) ****

I really like Parallel::ForkManager but the learning curve is steep.

You CANNOT use "next" inside the foreach loop!

foreach my $data (@all_data) {

$pm->start and next;

next if $something; ##BAD BAD BAD!!!

$pm->finish; # Terminates the child process

}

instead...

foreach my $data (@all_data) {

$pm->start and next;

if ($something) {

} else {

}

$pm->finish; # Terminates the child process

}

DateTime-Event-Sunrise (0.0501)

For version 0.0501 please apply patch from rt.cpan.org/Public/Bug/Display.html?i...

SOAP (0.28) *

SOAP is deprecated please try SOAP::Lite.

It's not a bad package just not what new development should be built against.

Geo-Coder-Googlev3 (0.11)

Use the drop in replacement Geo::Coder::Google::V3 it has support for the required parameter "sensor".

Geo-Point (0.93) ****

--- 2011-02-27 ---

Please ensure you update to version 0.93 to get area method to work correctly under UTM projection!

A working Geo::Line (Closed Ring) example...

perl -e '
use Geo::Point 0.93; use Geo::Line; #auto closes ring
printf "Area: %s (m^2)\n", Geo::Line->ring(points=>[[-77=>39],[-78=>39],[-78,38],[-77,38]], proj=>"wgs84")->in("utm")->area;
'

--- 2010-05-17 ---

Potential for a very powerful capability but documentation is limiting.

A working Geo::Point example...

perl -e '
use Geo::Point 0.93;
use Geo::Proj;
my $p=Geo::Point->longlat(qw{-77.03622 38.893631}, "wgs84");
my $epsg=26985; #SPCS83 Maryland zone (meters)
Geo::Proj->new(nick=>"md", proj4=>[init=>"epsg:$epsg"]);
printf "Point: %s\n", $p->in("md");
'

Apache-DBI (1.11) **

I tried this package to hit against Oracle but after much time. I gave up. I finally got apr-util-oracle to build against the oracle instant client by turning off the apr-util-ldap build.

%configure --with-apr=%{_prefix} \

--includedir=%{_includedir}/apr-%{apuver} \

--without-ldap --without-gdbm \

--with-sqlite3 --with-pgsql --with-mysql --with-freetds --with-odbc \

--with-oracle=/usr/lib/oracle/11.2/client64 \

--with-oracle-include=/usr/include/oracle/11.2/client64/ \

--with-berkeley-db \

--without-sqlite2

Geo-Ellipsoids (0.16)


Sys-RunAlone (0.10) *****

I think this package is great. Adding just one line gets you up and running. If you run crons against a database, there is no easier way to ensure that you never walk on yourself.

Date-Holidays-USFederal (0.01) **

The 0.01 version is no longer valid. Do not use >= 2011 until patched. The architecture needs a bit of an over haul anyway.

DBD-Oracle (1.30) *****

We use DBD::Oracle for 24/7 operations. I have not ever had an issue with it.

Now that Spacewalk has the RPMs it makes Fedora and RHEL easy to install and it is very nice just to have them built. I wish someone could just fix this license issue "Not compatible with Fedora licensing, as it requires oracle-instantclient-devel"

spacewalk.redhat.com/yum/latest/Fedor...
spacewalk.redhat.com/source/1.5/fedor...

Net-SCP (0.08)

This package is a wrapper around the scp system command. Look at Net::SFTP if you are looking for a pure Perl implementation for transferring files over the ssh protocol.

Net-SSH (0.09) ***

This package is a wrapper around the ssh system command. Look at Net::SSH::Perl if you are looking for a pure Perl implementation.

DBIx-Array (0.22)

See Review at www.perlmonks.com/?node=923676

txt2html (2.51) ****

This package just works out of the box (if you can get it installed). I've used HTML::FromText in the past but it needed a bit more tweaking to get it to work like I wanted.

My only issue is that the distribution is named after the script instead of the package which is typical CPAN practice.

Geometry-Formula (0.01) **

This package looks more like a programming exercise instead of a package to derive other projects. The interface would be a lot cleaner if it were more object oriented like...

my $sq=Geometry::Formula->new->square(side=>5);
print join ",", $sq->area, $sq->sides, $sq->perimeter, ...

25,4,20

Thanks,
Mike

mrdvt92

IO-Socket-IP (0.07)

I don't understand what the difference between this and IO::Socket::INET6 is? IO::Socket::INET6 has been around a long time and supports both IPv4 and IPv6.

Apache2-SOAP (0.73) *

Dependency SOAP::Transport::HTTP2::Apache is no longer available on CPAN.

Class-Easy (0.11) ****

Bottom line the "has" method supports a default value. I could not find any other lightweight "has" methods that do.

Documentation

- Needs better examples and documentation. For example, why do the tests use BEGIN blocks around has definitions.

- has mymethod => (); looks mush cleaner than has "mymethod";

Interface

- is=>"rw" would be a better default than is=>"ro" (for me anyway)

Ease of use

- Requirment for ExtUtils::MakeMaker >= 6.48 was pain. 6.42 worked fine with a couple of warnings.

Overall

I use as

perl -e '
package Foo;
use base qw{Package::New};
use Class::Easy;
has "hey", is => "rw", default => "cool";

package main;
print Foo->new->hey("Hey"), "\n";
'

Class-Builtin (0.04) ***

The lack of documented methods is a hugh limiting factor for this package. The general concept is great but I'm not quit sure where I'd want to use this functionality.

This list of methods should be part of the documentation.

perl -MClass::Builtin -e 'print("\n\n", ref($_)||"Scalar", "\n", OO($_)->methods->join("\n")) foreach("",[],{})'

Scalar
atan2
blessed
bytes
carp
chomp
chop
chr
clone
confess
cos
croak
crypt
decode
decode_utf8
defined
dump
encode
encode_utf8
exp
hex
index
int
isvstring
isweak
lc
lcfirst
length
log
looks_like_number
methods
new
oct
ord
pack
print
readonly
ref
refaddr
reftype
reverse
rindex
say
sin
split
sprintf
sqrt
substr
tainted
uc
ucfirst
unbless
unpack
utf8
weaken

ARRAY
blessed
carp
clone
concat
confess
croak
delete
dump
each
each_with_index
first
get
grep
isweak
join
length
map
max
maxstr
methods
min
minstr
new
pack
pop
poped
print
push
pushed
reduce
ref
refaddr
reftype
reverse
say
set
shift
shifted
shuffle
sort
splice
spliced
sum
unbless
unshift
unshifted
weaken

HASH
blessed
carp
clone
confess
croak
delete
dump
each
exists
get
isweak
keys
length
methods
new
print
refaddr
reftype
say
set
unbless
values
weaken

cpan2rpm (2.028) **

I loved cpan2rpm. But, it appears that Fedora now ships with cpanspec-1.78-3.fc12.noarch and not cpan2rpm.

It took a bit getting used to but I find putting the spec file in my MANIFEST is easiest.

It's a chicken and egg kind of thing

$ make dist
$ cpanspec PACKAGE-0.01.tar.gz
$ echo "PACKAGE.spec" >> MANIFEST
$ make dist #overwrite
$ rpmbuild -ta PACKAGE-0.01.tar.gz

And again, it would be great if "make spec" were part ExtUtils::MakeMaker.

RPM2 (0.69)

Plus: Package is maintained!

Minus: Object interface is not very "standard". (no new constructor)

Minus: Package is in root namespace. (Since the open_rpm_db method constructs an RPM2::DB object that is what the package should be called e.g. RPM2::DB->new). Still not sure why RPM2 namespace vs RPM namespace.

RPM-Info (1.07)

The interface is a little non-perlish.

I recommend an interface more like this.

use RPM:XXX;
my $obj=RPM::XXX->new;

foreach ($obj->search("foo")) {

printf "Name: %s\n", $_->name;

printf "Version: %s\n", $_->version;

printf "List: %s\n", join(", ", $_->list);
}

CouchDB-Client (0.09) *****

I needed an interface to CouchDB for my Storable::CouchDB package. I was planning to rewrite the interface as it is really quite simple. However, having this package made the effort fairly trivial.

There are a few awkward interface issues like the DB and DOC objects do not have "exists" or "persist" methods. They are lazy loading so they could. Currently, you have to ask the CLIENT object if the DB exists and the DB object if the DOC exists.

For Example:

something() if $doc->exists;

something() if $db->exists;

$doc->data($data);

$doc->persist; #store or create; just do it!

DateTime-Precise (1.05) *

DateTime::Precise is not a "DateTime" object and appears to no longer be maintained.

XML-LibXML-LazyBuilder (0.03) *****

I've built all of the XML for Geo::GoogleEarth::Pluggable based on this package. I think it is a great interface to the complications in building XML. I do have to say the documentation is a bit terse and the interface which returns a bunch of anonymous subroutines was a bit complicated to understand. But, it works and is rock solid.
Thanks,
Mike

mrdvt92

SQL-Easy (0.01) *

SQL-easy is in the wrong namespace it should be in DBIx-Whatever-Namespace. It has some of the capabilities of DBIx::Array.

DBIx::Array->sqlscalar = SQL::Easy->return_one
DBIx::Array->sqlarrayhash = SQL::Easy->return_data

Geo-ShapeFile (2.52) *****

Just what I needed! Thanks! Got a bunch of files from a client and could extract the points and data in one easy interface.

use Geo::ShapeFile;
use Data::Dumper qw{Dumper};

my $obj = new Geo::ShapeFile($file);

for my $index (1 .. $obj->shapes) {

my $shape = $obj->get_shp_record($index);

next unless $shape->shape_type == 1; #point

my $data = $obj->get_dbf_record($index);

my ($point)=$shape->points;

print join("\t", $index, $point->X, $point->Y), "\n";

print Dumper([$data]);
}

I would have given documentation a higher rating but I think the package needs a few more example scripts.

PerlQt (3.008)

This distribution puts all of it's packages in the root namespace.

Geo-GoogleEarth-Document (modules2)

Geo::GoogleEarth::Document is no longer being maintained please use Geo::GoogleEarth::Pluggable.

Net-eNom (0.02) ***

The package is in the wrong namespace. It should be WebService::eNom

HTML-FromText (2.05) ****

This is just what I was looking for a simple formated text to html converter. It was a bit hard to find with all of the wiki parsers out there but works well. Documentation is a bit limited but the test cases are there for review. If all of the tests were documented in the POD then I would rate this a 5 on documentation. Also, the interface and ease of use get dings since simple features like paras and bullets are turn off by default.

You may also want to look at HTML::TextToHTML.

WebService-UPS (0.11)

The package is called WebService-UPS but there is no WebService::UPS.

Win32-DriveInfo (0.06) ****

This was the only package that I could find on CPAN that could give me the Win32 drive percentage of free space.

perl -MWin32::DriveInfo -e "my @info=Win32::DriveInfo::DriveSpace(q{C:});printf qq{Percent of Free Space: %0.2f\%\n}, $info[6]/$info[5]*100;"

Percent of Free Space: 32.03%

Thanks,
mrdvt92

SQL-Abstract (1.22) ****

I just found this handy little package. I've done SQL building here and there but never again. The best thing... the output of SQL::Abstract methods are a direct input for DBIx::Array.

my $sabs=SQL::Abstract->new;

my $dbx=DBIx::Array->new;

$dbx->connect($connection, $user, $pass, \%opt);

my $count=$dbx->insert($sabs->insert($table, \%field));

my @data=$dbx->sqlarrayarray($sabs->select($table)); #whole table

I still need to find out how to use column aliases in the select.

XML-Simple (2.18) ****

I love XML-Simple. As a "data person", you just can't get better. I do always have to tweak the parameters and usually use ForceArray=>1. Typically, I construct with something like XML::Simple->new(XMLDecl=>1, RootName=>q{document}, ForceArray=>1);

Win32-OLE (0.1709) *****

I just want to say thanks for this module. I now never have to write ASP, VB, .Net again! My Win32::OLE::CrystalRuntime::Application module is a wrapper around this package and is rock solid. It runs multiple treads and has never had any issues.

Path-Class (0.23) *****

2009-01-20 - I just found this module and I love it. I'm a bit concern with importing functions named "dir" and "file". But, I just import what I need. use Path::Class qw{file}; -mrdvt92

2011-02-16 - Two years later and still one of the best tools in the CPAN! - mrdvt92

DBIx-DWIW (0.48)

This package is very simular to my DBIx::Array in concept.

File-Stat-OO (0.03) ***

2011-02-23 - I now use Path::Class for all my needs.

2008-12-16 - I use this package since it's easy. It would be nice if the object supported ->basename and ->dirname properties as I keep needing them at the same time. This syntax is not documented File::Stat::OO->new({use_datetime=>1});

Image-Resize (0.5) ***

I needed all of my images to be 150x150 and not stretched just centered and white padded. So, this package did not work for me.

$image->resize(150, 150, 0); #Stretched
$image->resize(150, 150); #is not 150x150 but is either 150x??? or ???x150 keeping original ratio.

Geo-Coder-Google (0.03) ****

I like this package. We actually use this for a few of our production systems. We do have an enterprise Google API key. I always add
use Time::HiRes qw{sleep}; sleep(0.2); in loops to be nice to Google.

Google limits you to about 1000 hits.

Config-IniFiles (2.39) *****

Use for both Win32 and Linux platforms. Works great.

Data-GUID (0.043) *****

Made it very easy to support GUIDs for our system.
Simply ...

print Data::GUID->new->as_string;

Geo-Lookup-ByTime (0.10)

Simular to Geo::Spline

geo-ecef (1.0.0)

We have moved this module to Geo::ECEF. Please use that version.

DateTime-Format-Oracle (0.03) ***

Thanks for the package but using %ENV is just not the way I prefer to pass variables around. It would be nice if the interface where more like.

use DateTime::Format::Oracle;

my $dtfo=DateTime::Format::Oracle->new(

format=>'YYYY-MM-DD HH24:MI:SS');

my $dt = $dtfo->datetime('2003-01-16 23:12:01');

my $dt = $dtfo->dt('2003-01-16 23:12:01');

my $string = $dtfo->string($dt);

$dtfo->format('YYYY-MM-DD HH24:MI:SS'); #set format

my $format=$dtfo->format; #get format

Thanks,
Mike (mrdvt92)

HTML-EasyTable (0.04) *

use CGI; #instead
my $q=CGI->new;
my @table=([qw{a b c}], [qw{1 2 3}], [qw{4 5 6}]);
my %opt=(border=>1);
print $q->table(\%opt, $q->Tr([map {$q->td($_)} @table]));

GPS-Tools (0.01) *

This package is here as an archive of code more than a great package.

Data-Convert-MicrochipTechnology-Float (0.03)

Only place on the net.

Geo-Proj4 (0.99) *****

Great interface to the PROJ.4 lib.

Geo::Proj4->new(init => "epsg:$epsg") is the only constructor that I use!