Path::Class and File::Copy (perl-5.10)
Chisel Wright
chisel at herlpacker.co.uk
Tue Aug 26 10:40:59 BST 2008
I foolishly extended the test suite for one of my modules last week;
after fixing stupid omissions I started getting Failed Test reports.
They're all from 5.10.0 and are of the form:
Argument "/some/file" isn't numeric in numeric
eq (==) at /path/tolib/5.10.0/File/Copy.pm line 70.
After installing 5.10.0 I tracked this down to File::Copy::_eq() and
Path::Class objects.
sub _eq {
return $_[0] == $_[1] if ref $_[0] && ref $_[1];
return $_[0] eq $_[1] if !ref $_[0] && !ref $_[1];
return "";
}
The problem is down to ref($_[x]) being a Path::Class::File, causing the
"==" comparison to be made ... using $_[x] in scalar context causing it
to stringify.
I've solved the problem locally by making my call look like:
copy(
file($dir1, $file1) . q{},
file($dir2, $file2) . q{},
);
But it just feels wrong and icky.
What are people's thoughts on the best way to resolve this going
forwards?
Should I stick with my ".q{}" solution?
Should _eq() be extended to handle the passing of something like a
Path::Class::File object?
I don't think Path::Class itself is doing anything "wrong" - it
stringifies when I expect it to usually.
Here's a script that demonstrates the issue for the curious/interested -
remember it'll only fail with the newer File::Copy from 5.10.0
---- t/01.path-class.t ----
#!/usr/bin/env perl
# vim: ts=8 sts=4 et sw=4 sr sta
use strict;
use warnings;
use Test::More tests => 11;
# show the verson of perl we're running the tests as
diag sprintf "version is v%vd\n", $^V;
use_ok 'File::Copy';
use_ok 'File::Temp', qw(tempfile tempdir);
use_ok 'IO::File';
use_ok 'Path::Class';
# create a temporary directory
my $dir = tempdir( CLEANUP => 1 );
# get names for our two files
my $file1 = file($dir,q{file1});
my $file2 = file($dir,q{file2});
# make sure they're the objects we expect
isa_ok($file1, 'Path::Class::File');
isa_ok($file2, 'Path::Class::File');
# a couple of like() tests for stringification confirmation
like($file1, qr{file1$}, q{$file1 name is like 'file1'});
like($file2, qr{file2$}, q{$file2 name is like 'file2'});
# make a tempfile
my $fh = new IO::File $file1, "w";
if (defined $fh) {
print $fh "bar\n";
$fh->close;
}
# check it exists
ok (-f $file1, q{source file exists});
# check the destination file does not exist
ok (! -f $file2, q{destination does not exist yet});
# now copy file1 to file2
copy($file1, $file2);
# the destination file _should_ exist now
ok (-f $file2, q{destination file exists});
# this is the offending method from /opt/perl/lib/5.10.0/File/Copy.pm
# sub _eq {
# return $_[0] == $_[1] if ref $_[0] && ref $_[1];
# return $_[0] eq $_[1] if !ref $_[0] && !ref $_[1];
# return "";
# }
#diag _eq($file1, $file2);
---- t/01.path-class.t ----
Chiz
--
Chisel Wright
e: chisel at herlpacker.co.uk
w: http://www.herlpacker.co.uk/
I may be a pretty sad person, but I don't make jokes in base 13.
More information about the london.pm
mailing list