flobo flobo - 9 months ago 40
Perl Question

Sgf2dg and Perl: Use of uninitialized value $_ in pattern match (m//)

As the title of my question suggests, I encountered the following problem:

Use of uninitialized value $_ in pattern match (m//)

in line 1416 of Sgf2Dg.pm
of the sgf2dg package.
There it says:

} elsif (($arg eq '-break') or ($arg eq '-breakList')) {
my $breaks = '';
while (@ARGV and
$ARGV[0] =! m/[\d,]*/) {
$breaks .= shift @ARGV;
@{$option{breakList}} = sort {$a <=> $b} split(/,/, $breaks);

Therefore I suppose the problem has something to do with the pattern match
=! m/[\d,]*/
, but I don't know enough
to deal with this myself, nor enough to present you with a simple MWE :(

I have installed sgf2dg and it runs without a problem. I can use all the options except for the
one, but that's the one I want. On Linux terminal:

sgf2dg -break 0 test.sgf

is a typical smart game format file. Without the
-break 0
option it runs without any problem.

For your convenience I attach an sgf file here:



That's a bug in the code.

$ARGV[0] =! m/[\d,]*/ really means $ARGV[0] = (! m/[\d,]*/), i.e. assign the negated result of m/[\d,]*/ to $ARGV[0]. And m/[\d,]*/ matches against $_ by default, but $_ isn't set at that point.

The less-incorrect code would be $ARGV[0] =~ m/[\d,]*/ (a match of [\d,]* against $ARGV[0]), but that's semantically wrong: [\d,]* always matches, so that condition would be always true.

It looks like it's supposed to check that the argument consists of digits and commas only, for which the correct code would be $ARGV[0] =~ m/\A[\d,]+\z/.

However, according to the documentation, -break only accepts one argument, so that whole block could be replaced by:

} elsif (($arg eq '-break') or ($arg eq '-breakList')) {
    my $breaks = shift @ARGV;
    @{$option{breakList}} = sort {$a <=> $b} split(/,/, $breaks);