Reviews by Christopher Bottoms


File-Monitor (1.00)

File::Monitor __works in shared filesystem environment__ in which changes can be made by many different compute nodes (or the head node). I tested File::Monitor by running the monitor on the head node and making changes using a different node.

This is in stark contrast to Inotify-based modules and even Perl 6's notifications of file system changes ( which only work if changes are made by the same system on which the monitoring process is running.

Anyway, I'm so happy to find this module. Once I get to know it better, I will commit to a "star rating". I expect and hope it will be five stars.

File-Slurp (9999.19) *****

If you want to read the entire contents of a file into a string, this is the module for you! I use it all the time. The alternative for only the "read_file" or "slurp" function it provides is the following:

# Read entire file into one string
sub read_file {

my $filename = shift;

my $text = do { local( @ARGV, $/ ) = $filename ; <> } ;

return $text;

Do you really want this function copied and pasted throughout your code base? Just Don't repeat yourself (DRY) and

use File::Slurp qw(read_file)


File-Find-Wanted (1.00) *****

Works great!

The Synopsis is clear enough that I was able to use this several years ago as a Perl neophyte, despite not knowing what a callback was.

As Andy mentions in the Synopsis, if you really do need a set of complex rules to identify the files you want, check out File::Find::Rule. However, nine times out of ten, you probably don't need anything more than the ease and simplicity of File::Find::Wanted.

LSF (0.9) *****

If it doesn't install for you the first time, try applying the patch found here:

After applying this very simple patch, this module works great under Perl 5.14.1 running on a RedHat Enterprise Linux 5.8 cluster using Platform LSF HPC 7 Update 6.

Data-Show (0.001001) *****

brian d foy may have said that "plain ol' print" was the "best debugger" in his book Mastering Perl. But I think that was only because Data::Show had not been invented yet.

Data::Show gives you (1) the name of the variable you want to "show", (2) the contents of that variable in a readable format, (3) the line the variable is located on, and (4) the file that line is located in.

What more could you want to help simplify your debugging?

MooseX-Iterator (0.11) ****

UPDATE (version 0.11)
I am very grateful that Robert created this. I was about to create my own when I found this.

If you don't plan on using the peek function, everything should behave as you would expect.

If you are going to use the peek function, however, make sure you understand how it works. In version 0.11, it returns the value _after_ the value that next would return, instead of the same value that next would return.

To get around this, I implemented the following.

#ABSTRACT: Create a closure for iterating over an array
package MyIterator;
use 5.010;
use Moose;
use MooseX::Iterator;
use Carp qw{ croak };

sub generate_peekable_array{

my %opts = @_;

my $aref = $opts{aref}

// croak 'the key "aref" is not optional';

my @array = @{ $aref };

my $num_to_pop = $opts{pop} //= 1;

my $should_peek = $opts{peek} //= 0;

my $num_elements = @array;

if( $num_elements % $num_to_pop != 0){

croak "array of '$num_elements' is not "

. "divisible by 'pop' number of '$num_to_pop'";


my $peekable_array = MooseX::Iterator::Array->new(

collection => \@array,


return sub {

my @array;

if ($should_peek) {

my $penultimate = $num_to_pop -1;

for ( 1 .. $penultimate ) {

push @array, $peekable_array->next;


#peek gives the value that will be available after calling next

my $next_value = $peekable_array->peek;

push @array, $peekable_array->next;

push @array, $next_value;


else {

for ( 1 .. $num_to_pop ) {

push @array, $peekable_array->next;



return @array;




I was just getting ready to create my own iterator for my Moose attribute, when I found this.

Here is working code from my current project using this module:

has 'row_iterator' => (

is => 'ro',

isa => 'MooseX::Iterator::Array',

lazy => 1,

default => sub {

my $self = shift;

MooseX::Iterator::Array->new( collection => $self->{rows} );