Subject: | CAM::PDF::rangeToArray is broken |
Perl version: v5.8.4 built for i386-linux-thread-multi
OS: Linux 2.6.8-2-386
The documentation of the subroutine CAM::PDF::rangeToArray reads as follows.
--------------------------------
Converts string lists of numbers to an array. For example,
CAM::PDF->rangeToArray(1, 15, '1,3-5,12,9', '14-', '8 - 6, -2');
becomes
(1,3,4,5,12,9,14,15,8,7,6,1,2)
--------------------------------
This is not true. Instead it returns (3,4,5,14,15,8,7,6).
The wrong code is this loop beginning in line 5662:
for (@in_array) # modify in place
{
s/ [^\d\-,] //gxms; # clean
m/ ([\d\-]+) /gxms; # split on numbers and ranges
}
While the substitute really changes the array elements, the match
doesn't. The following chunk replaces your grep for getting the defined
ones of the passed parameteres and applying your regexes to them:
my @in_array = map
{
defined $_ ? do
{
my $entry = $_;
$entry =~ s/ [^\d\-,] //gxms; # clean
$entry =~ m/ ([\d\-]+) /gxms; # split on numbers and ranges
} :
()
} @_;
This does not only work as expected (and documented), it is also a
little faster, since each array element is processed only once (map)
instead of twice (grep + for).
I attached a patch against the latest version of CAM::PDF.
Subject: | 20070306-01-CAM-PDF.pm.patch |
Index: PDF.pm
===================================================================
RCS file: /studium/Diplomarbeit/PDF.pm,v
retrieving revision 1.1
diff -u -r1.1 PDF.pm
--- PDF.pm 5 Mar 2007 18:05:19 -0000 1.1
+++ PDF.pm 6 Mar 2007 15:26:53 -0000
@@ -5657,13 +5657,17 @@
my $pkg_or_doc = shift;
my $min = shift;
my $max = shift;
- my @in_array = grep {defined $_} @_;
- for (@in_array) # modify in place
+ my @in_array = map
{
- s/ [^\d\-,] //gxms; # clean
- m/ ([\d\-]+) /gxms; # split on numbers and ranges
- }
+ defined $_ ? do
+ {
+ my $entry = $_;
+ $entry =~ s/ [^\d\-,] //gxms; # clean
+ $entry =~ m/ ([\d\-]+) /gxms; # split on numbers and ranges
+ } :
+ ()
+ } @_;
my @out_array;
if (@in_array == 0)