Reviews by Toby Inkster

cpanratings
 

RSS

List-Objects-WithUtils (2.010002) *****

I agree with educated_foo that doing $list->push(@items) is no win over push(@$list, @items). However, that's not where List::Objects::WithUtils objects shine.

What they are useful for (and this is something the documentation could better emphasise) is use as attribute values (or in Java terminology "members") in object-oriented programming. $widget->valves->push(@more) feels nicer than push @{ $widget->valves }, @more. And thanks to Moose/Mouse/Moo's method delegation features, can easily become just $widget->push_valves(@more) which is nicer still. (q.v. Law of Demeter.)

System-Command (1.108) *****

When you need to do something simple with an external command, Perl already hands you all the tools you need. There's the system() built-in, and of course backticks (a.k.a. the qx operator).

However, if things get more complex - for example you need to run a command and chat to it, passing data to its STDIN and receiving data from STDOUT - the code you need to write isn't quite as neat. These sorts of tasks can usually be accomplished by digging around in the IPC modules that come bundled with Perl, but you don't need to because BOOK has done that for you!

System::Command provides a very neat little object-oriented wrapper around launching and chatting to external processes. It provides convenient options for establishing the process' environment and working directory. Once the process is running, it will give you filehandles to interact with it.

For a while System::Command had problems on Windows which made it an unattractive prospect to those wanting to write cross-platform code, but these issues have been resolved now.

Cache-Moustache (0.002)

Previous reviewer is an idiot.

Evidence: He gave Cache-Moustache a star. It deserves no stars.

MooseX-Meta-Attribute-Lvalue (0.05)

I recently took over maintenance for MooseX-Meta-Attribute-Lvalue, and have renamed the distribution MooseX-LvalueAttribute.

The latest versions use Variable::Magic to ensure that type constraints, coercions, triggers, etc, *do* get called in lvalue context.

Codes (1) **

This distribution only offers one-way lookup, allowing you to look up a country's name from its ISO 3166-1 alpha-2 code, but not vice versa. It doesn't support ISO 3166-1 alpha-3 codes, nor ISO 3166-1 numeric codes.

Despite being newly uploaded, this distribution is missing several recently created countries, such as Sint Maarten which has been a country with an ISO code of "SX" since 2010, and South Sudan which has been independent since 2011, and has ISO code "SS".

I'd recommend using the more established module Locale::Codes::Country instead.

HTTP-Tiny (0.029) ****

Very handy little module for when you just need HTTP.

LWP::UserAgent is arguably nicer, but when you're just trying to access a JSON API you start asking yourself, "what the hell do I need to install HTML::Entities and IO::HTML for?"

And because HTTP::Tiny and JSON::PP are available in Perl core (since 5.14) using JSON APIs from Perl have become very convenient.

App-perlbrew (0.63) *****

I've recently used perlbrew to help debug a particular issue that was only occurring in Perl < 5.16; and another issue in another module that was effecting Perl < 5.18.

It is incredibly handy to be able to switch back and forth between Perl versions to compare behaviour.

CGI (3.63) **

CGI.pm is the grand old man of Perl web programming. It is not generally considered to be the state of the art any more. While it's still maintained for bugs, and occasional minor new features are added, don't expect too many exciting new ground-breaking features to be added.

CGI.pm essentially has two main areas of functionality:

1. handling communication with the web server via the CGI protocol (parsing query strings, interpreting environment variables, outputting HTTP headers, etc); and
2. generating HTML using function calls.

It seems to be fairly widely agreed that the HTML generation part is best forgotten about - instead, try a template module like Text::Template or Template::Toolkit, or try building an in-memory object which can be serialized to (X)HTML, like an XML::LibXML document.

The CGI protocol stuff is more reasonable to be using into the 21st century, however it does limit your scripts to running via the CGI protocol. Developing using Plack, or a Plack-based framework instead allows you to write scripts that run not just via CGI but in other environments (mod_perl, FastCGI, etc) too.

The API is somewhat odd, as it offers both object-oriented and functional interfaces and allows you to switch between them at will. Frameworks like CGI::Application and CGI::Snapp go some way to protecting you from that.

Pod-Simple (3.28) ****

There's no disputing the quality of Pod::Simple's Pod parsing. It's pretty much the reference implementation.

However, the internals are somewhat byzantine. If you want to subclass Pod::Simple::HTML, prepare to trace method calls through five levels of inheritance (your class, ::HTML, ::PullParser, Pod::Simple, ::Blackbox), the last of which contains the following comment:

###############################################
##
## stop reading now stop reading now stop reading now stop
##
## HERE IT BECOMES REALLY SCARY
##
## stop reading now stop reading now stop reading now stop
##
###############################################

It's not a pleasant experience. My advice is to avoid subclassing it if possible; just pre-process the input or output to get what you need. Only subclass if there's no other way to accomplish what you need.

Test-DescribeMe (0.004) ****

A nice, declarative way of skipping certain test scripts based on a standard set of environment variables.

Although I like that WOLFSAGE has split the logic of detecting the environment (Test::Settings) and the declarative skipping (Test::DescribeMe) into two modules, releasing these modules as separate distributions seems like overkill. I can't imagine anyone who wanted to install Test::Settings baulking because Test::DescribeMe was bundled.

Eval-Closure (0.08) *****

This is the kind of module that 99% of Perl users will probably never directly need to use, but is a vital dependency for things like Moose to prevent them being slow. (Or at least, prevent them from being *hideously* slow.)

I started using it in Type::Tiny quite a bit, but was deterred by its use of Sub::Exporter, which although itself a great tool, introduces quite a list of dependencies, which would have been inappropriate for a "*::Tiny" module.

I ended up re-implementing most of Eval::Closure as Eval::TypeTiny and bundling that. Nevertheless, in future projects I'd still certainly consider using Eval::Closure, especially if the project already had a direct or indirect dependency on Sub::Exporter.

experimental (0.003) *****

experimental.pm doesn't do anything amazingly complex; it just eliminates the need for the rather annoying incantation:

no if ($] > 5.017011), warnings => "experimental::smartmatch";

... which is necessary to eliminate smartmatch-related warnings in Perl 5.18.

I'd been toying with an idea to release such a module myself, but thanks to LEONT I don't have to. Hurrah!

Test-HTTP-Server (0.03) ****

This is a handy little tool for testing modules that need to be on the client side of an HTTP transaction.

However, it sadly doesn't currently run on Windows (except cygwin), so you need to remember to check the platform in your test script, and skip_all if it's Windows.

Try-Tiny-ByClass (0.01) ****

Nice extension to Try::Tiny to make it simple to catch a collection of different exception classes and behave accordingly.

Its one weak point is that it has no facility to catch strings, which are quite commonly thrown by many Perl core modules and popular CPAN modules, even if your policy within your application is to always use exception objects. (Try::Tiny::SmartCatch is an alternative without this limitation, but with somewhat more verbose syntax.)

utf8-all (0.010) *****

utf8::all helps you stop thinking about Unicode. Configure your editor to save files in UTF-8, use utf8::all at the top of each file, and that's 95% of your Unicode handling needs covered.

Test-Fatal (0.010) ****

Test::Fatal is a good replacement for Test::Exception. I find myself using it a lot. It is very low in dependencies (only non-core dependency is Try::Tiny), which makes it quite easy to bundle along in "inc".

The one missing feature which I find myself wishing for occasionally is the ability to test the exception for a string of Perl code. (Consider the two forms of Perl's "eval" keyword.)

Mail-Sendmail (0.79) ****

It's ancient and it's quirky, mysterious and spooky; it has its limitations. However it's damn simple to use, so it's my go to module for quick one-off scripts that need to send mail.

For anything more involved, I'd recommend Mail-Box.

Spellunker (v0.2.7) *****

I've been using Test::Spellunker for a few weeks now to check pod spelling, and have been pleased with the results.

It provides a similar API to Test::Spelling, but rather than shelling out to the first spell checker it can find on the system, does a pure Perl spell check. This means you get more consistent results across different systems, including Win32.

Initial loading of the bundled dictionary is noticeable (about 1.5 sec on this old netbook), but once it gets going, testing each pod file is very fast.

Documentation is a little patchy, but it's pretty easy to use anyway so that's not a big problem.

XML-Simple (2.20) *

For any XML work where any of the following is true, XML::Simple is not your friend:

* The order of elements is important.

* The distinction between an element and an attribute is important.

* You want to preserve comments.

* You want to preserve whitespace.

* Some elements have mixed content (i.e. an element which contains some text data mixed in with child elements)

* You need to support namespaces

It's not that there's anything wrong with XML-Simple's implementation; the problem is with the entire concept of mapping between arbitrary XML and plain nested hashes/arrays.

An XML element is conceptually something like the simultaneous combination of a scalar string (the element name), a hash (the element's attributes and their values), and an array (the element's contents). You could model it like that with an overloaded object, but that approach doesn't seem to have caught on.

Something like XML-Rules, which is designed to be configured for a particular flavour of XML first, will provide a reasonable solution to map between XML and plain nested hashes/arrays, for some flavours of XML. (It's mostly suitable for data-centric XML rather than document-centric; think Atom, but not XHTML.)

Other than that, using a generic DOM or event-driven XML tool (like XML-LibXML or XML-Twig) will save you pain in the long term.

XML-Simple's simplicity might lure you in, but can end up causing you problems and confusion later on. (In fairness to the module's author, he does note XML-Simple's limitations in the pod.)

Module-Advisor (0.09) ****

This is a nice idea - a module that tells you about CPAN packages you have installed that have known security issues, performance issues or serious bugs, and which should be upgraded.

My only gripe is that it only tells you about problems which Module::Advisor's maintainer (TOKUHIROM) is aware of. It would be great (albeit perhaps a little slow) if it used some sort of online service to fetch data about problematic CPAN packages that could be updated by the authors of those packages.

Acme-Math-PerfectChristmasTree (0.01) *****

If only this module had been available a few weeks earlier; then my Christmas tree wouldn't be so damn imperfect.

Ez-Tf (0.1.2.2) *

DO NOT USE.

This module has apparently been deprecated with the release of the clearly far superior Testing::Values::Boolean.

Module-Quote (0.001)

Steven, the module came about partly due to noodling around on the ideas behind www.modernperlbooks.com/mt/2012/11/fu...

App-gist (0.13) *****

Works as advertised. (Can there be any higher praise?)

Promises (0.01) *****

Truly well-written documentation. Just reading the pod was an education.

I don't do much async programming in Perl, but next time I do, I will "use Promises".

Class-Method-Modifiers-Fast (0.041) ***

This module (CMMF) works, but despite the name is actually slower than Class::Method::Modifiers (CMM). At some point in history CMMF may have been faster than CMM perhaps, but not any more.

Benchmark results:
gist.github.com/4001692

CMM has fewer dependencies, and offers good integration with Role::Tiny, Moo and thus Moose. I can't think of any good reason to use CMMF over CMM.

Moo (1.000005)

This is a quick response to dirk's review. Although the documentation may make the list of missing features sound like they're just mst's whims (and some probably are), there is sound reasoning behind many of them.

If you read Moose::Manual::BestPractices you'll see:

* Avoid lazy_build

* Don't use the initializer feature

* Use Moose::Meta::Attribute::Native traits instead of auto_deref

And, directly quoting from Moose's author regarding augment/inner: "Thankfully, only a small percentage of people actually grok this feature and of those people only a handful of them are crazy enough to try and use it."

Augment/inner is hard to implement right; there are serious bugs lurking under the surface of Moose's implementation. It wouldn't be especially valuable for Moo to add another broken augment/inner implementation to CPAN.

Moo is not compatible with Moose in the same sense that Mouse is, where you can just replace "use Moose" with "use Mouse" and almost everything Just Works.

Moo is compatible in a different way - Moo classes can consume Moose roles; Moose classes can consume Moo roles; Moose classes can extend Moo classes; etc. In my opinion this is a more useful kind of compatibility.

aliased (0.30) *****

This module, like say constant.pm, implements a very simple idea, and something that can easily be achieved without a module, but it's something that you probably wouldn't bother doing unless there was a module to do it; so I'm glad that there is a module to do it.

JSONY (0.0.3) ****

Only at version 0.0.3, and I'm already recommending it for dealing with broken JSON.

www.perlmonks.org/?node_id=994212

PerlX-MethodCallWithBlock (0.05) *****

This module allows such beautiful code when dealing with objects that accept coderefs (e.g. XML::LibXML::NodeList) that it makes me want to weep with joy.

This syntactic enhancement should be added to perl itself.

Hook-AfterRuntime (0.005) *****

A simple idea, but it works, and is very useful.

Catalyst-Runtime (5.90015) ****

Catalyst is a well-written MVC framework, however it is billed as the one-stop solution to developing largish web applications in Perl, but in my experience it's no panacea.

For some projects MVC may be a good fit, but for others it seems to be a hindrance. If MVC is right for your project, then Catalyst is almost certainly the MVC framework you should be using; but don't just *assume* that MVC is right for you. Investigate other options first.

For many projects, sitting directly on top of Plack without an intermediate framework may be a better option.

See also www.slideshare.net/kiphampton/magpie-...

namespace-sweep (0.004) *****

namespace::autoclean done right.

namespace-autoclean (0.13) ****

If you're already using Moose, and aren't doing any overloading, then this module works very well. Otherwise, namespace::sweep seems to work better.

List-MoreUtils (0.33) *****

This module is so vital to everyday use of Perl that it makes me wonder why oh why Perl comes bundled with modules that implement HTTP server push and NNTP, but doesn't come bundled with List-MoreUtils! Hell, the 'first' and 'uniq' functions should plain old be part of the Perl language itself.

Module-Package (0.30) *****

I now use Module-Package to package up all my CPAN releases. (In particular, I use Module-Package-RDF.) It's mostly just a wrapper for Module-Install (itself a wrapper for the venerable EUMM), but it just makes life easier.

Sub-Exporter (0.984) *****

Sub::Exporter allows your module's caller to import your functions using their own choice of name. Even if that were the only difference between Exporter.pm and Sub::Exporter it would be well worth switching to the latter. But it's not! Sub::Exporter also gives you generators, which are another awesome feature.

The one drawback of this module is that if you want your import() routine to do something else as well as exporting symbols to the caller, it becomes a little more tricky than with Exporter.pm. It can be done but it ain't pretty. (Hint: write a custom installer.)

XML-LibXML (2.0002) *****

OK, so it's not pure Perl, and some people theoretically might have trouble installing it as a result of that, but... it's very fast, very reliable and very correct in everything it does.

Path-Class (0.26) *****

If you need to work with files (and who doesn't?!) then you want to use this Path-Class. End of story.

Well, not quite end of story. You may also want to check out Path-Class-Rule.

RDF-Trine (1.000) *****

RDF-Trine (and companion RDF-Query) is *the* toolkit to use if you want to do any RDF or Semantic Web programming in Perl. It is the foundation which most other Perl RDF tools (RDF-Endpoint, RDF-LinkedData, Test-RDF, etc) build upon.

App-Cmd (0.318) *****

While the structure of the documentation could stand to be improved (the Tutorial document is more a collection of random extra thoughts that couldn't be slotted into the documentation elsewhere), this makes building command-line interfaces a breeze.

It's the PSGI of the command-line world.

LWP-Curl (0.10) ***

An excellent idea!

cURL is a great HTTP library, but for some reason scripting language bindings for it (PHP and Perl are the ones I've tried) pretty much exactly follow the cURL C API, which is pretty horrible.

LWP-Curl takes WWW::Curl::Easy and wraps it in the LWP interface which should be already familiar to pretty much anyone who's done any WWW scripting in Perl.

It's not a complete implementation of the LWP API, but the TODO section of the documentation notes that this is planned.

Marked it down on the "overall" score because Makefile.PL does not include correct dependency information. For example it lists WWW::Curl::Easy as a "build_requires" dependency, when it's actually a run-time dependency.

Web-Magic (0.008)

It wouldn't be a lot of work to write my own random_jackbauer_fact method and drop the dependency on Acme::24, but I don't believe in reinventing the wheel.

If LWP::Simple does enough for you, then great. Personally I want to do more with web resources than print them to STDOUT and store them in files. Web::Magic is not HTTP::Tiny, nor does it try to be. LWP::Simple and HTTP::Tiny are great, and nobody needs me to write another one. But they can't do things like this:

perl -MWeb::Magic -E'printf "%s -- %s\n", $_->title, $_->author for Web::Magic->new("http:/ /search.twitter.com/search", q => "Perl")->entries'

(note: space added between slashes to avoid cpanratings' automatic linkifying)

Syntax-Feature-Qwa (0.001)

seano, the savings in terms of characters are modest (at least for the qwa and qwh keywords - qwk saves more). Like most of the rest of the Syntax::Feature::* namespace, it doesn't do anything amazingly complex - the primary benefit is the ability to write more declarative code, not to reduce source code disk space usage.

Smart-Dispatch (0.002)

This is an author comment.

seano if you do not want, then do not download. Very simple solution.

Smart::Dispatch has three non-core dependencies - namespace::clean, Sub::Exporter and Any::Moose. These in turn (namespace::clean in particular) have other dependencies, but not a massive number. These dependencies are announced in META.yml as per usual for CPAN distributions - nothing obscure about it. (Excepting the fact that YAML itself is pretty obscure.)