Skip Menu |

This queue is for tickets about the Scalar-List-Utils CPAN distribution.

Report information
The Basics
Id: 127943
Status: open
Priority: 0/
Queue: Scalar-List-Utils

People
Owner: Nobody in particular
Requestors: dlamblin [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: List::Util reduce oddly repeating input
Date: Thu, 6 Dec 2018 20:46:04 +0900
To: bug-Scalar-List-Utils [...] rt.cpan.org
From: Daniel Lamblin <dlamblin [...] gmail.com>
I'm getting a seemingly randomly chosen single input being repeated for input to reduce. EG a {say "$a $b";$hash{$a}<$hash{$b}?$a:$b} inside a reduce block is just printing out: a 380 a 380 over and over, with 380 not even being one of the items in the list of keys passed in. This happens in Perl 5.28 (homebrew built) and Perl 5.18 (system build) on a Macbook. Here's some examples where things are normal: ~$ perl -MList::Util=reduce -E'say reduce {say "$a $b";$a>$b?$a:$b} 1..3' 1 2 2 3 3 ~$ perl -MList::Util=reduce -E'%h=();map{$h{$_}=3-$_}1..4;say reduce {say "$a $b";$h{$a}>$h{$b}?$a:$b} keys %h' 3 2 2 4 2 1 1 ~$ perl -MList::Util=reduce -E'%h=();map{$h{$_}=3-$_}1..3;say reduce {say "$a $b";$h{$a}>$h{$b}?$a:$b} keys %h' 2 3 2 1 1 ~$ perl -MList::Util=reduce -E'%k=();map{$k{$_}=4-$_}1..4;say reduce {say "$a $b";$k{$a}>$k{$b}?$a:$b} grep {$k{$_}>-0} keys %k' 3 1 1 2 1 But when trying to solve https://adventofcode.com/2018/day/6 I wrote some code where top level I defined my $b and assigned something to it (380) for the example, and then things just didn't work right with it. Here's a reproduction of the problem minimally: ~$ perl -MList::Util=reduce -E'use warnings;use strict;use feature ":5.28";my ($b,%k)=(100,());map{$k{$_}=4-$_}1..4;say reduce {say "$a $b";$k{$a}>$k{$b}?$a:$b} grep {$k{$_}>0} keys %k' 3 100 Use of uninitialized value in numeric gt (>) at -e line 1. 3 100 Use of uninitialized value in numeric gt (>) at -e line 1. 3 Compared to not setting $b: ~$ perl -MList::Util=reduce -E'use warnings;use strict;use feature ":5.28";my %k=();map{$k{$_}=4-$_}1..4;say reduce {say "$a $b";$k{$a}>$k{$b}?$a:$b} grep {$k{$_}>0} keys %k' 1 2 1 3 1 So; I was surprised to have this happen, I thought the $a and $b in the block would be locally scoped. Is this a bug? If so is it mentioned somewhere that this pre-defined $b thing is a known issue or gotcha? My Advent of Code attempt is here [apologies re:style]: #!/usr/bin/env perl use warnings; use strict; use feature ":5.28"; use List::Util qw/reduce min max/; use POSIX "ceil"; my @z=("a".."z","A".."Z","0".."9");my$x=0; my ($n,%p,%e,@x,@y)=('aa',()x4); for (<DATA>){ m/^(\d+), (\d+)$/; #($p{n}{a}, $p{$n}{x}, $p{$n++}{y}) = (0, int($1), int($2)); ($p{$z[$x]}{a}, $p{$z[$x]}{x}, $p{$z[$x++]}{y}) = (0, int($1), int($2)); push @x, int($1); push @y, int($2); } my ($l,$r,$t,$b) = (min(@x), max(@x), min(@y), max(@y)); $l -= ceil($r/9); $r += ceil($r/9); $t -= ceil($b/9); $b += ceil($b/9); sub d{my($x, $y, $i, $j) = @_; abs($x - $i) + abs($y - $j)} sub c{ my ($x, $y) = @_; my ($k, $n, $d) = ((0)x2,$r+$b); for (keys %p){ ┆ ┆$n = d($x, $y, $p{$_}{x}, $p{$_}{y}); ┆ ┆$k .= "_$_" if ($d == $n); ┆ ┆($k, $d) = ($_, $n) if ($d > $n); } ($k, $d); } for my $j ($t..$b){ for my $i ($l..$r){ ┆ my ($k, $d) = c($i, $j); ┆ $p{$k}{a}++ if $p{$k}; ┆ if ($i==$l || $i==$r || $j==$t || $j==$b){ ┆ ┆ $e{$k} = 1; ┆ } ┆ #print $p{$k} ? $k : "."; } #say""; } say map {sprintf "%2s:%3d,%3d=%5d\n",exists $e{$_} ? "^$_" : "=$_",$p{$_}{x},$p{$_}{y},$p{$_}{a}} sort keys %p; say "None of: ".join(" ", sort keys %e); say "Only of: ".join(" ", sort grep {!exists $e{$_}} keys %p); my $k = reduce {say "$a $b"; $p{$a}{a} > $p{$b}{a} ? $a : $b} grep {!exists $e{$_}} keys %p; say "WHAT"; say "$k at $p{$k}{x}, $p{$k}{y} is $p{$k}{a} big." #There's more data but, you don't need it do you? __DATA__ 81, 157 209, 355 111, 78 179, 211 224, 268 93, 268 237, 120 345, 203 72, 189 298, 265 190, 67 319, 233 328, 40 323, 292 125, 187 343, 186 46, 331 106, 350 247, 332 349, 145 217, 329
The $a and $b used by reduce are package globals. Their values are localized during the reduce operation. If you use a lexical of the same name, it will shadow the global, and the lexical will be used by your reduce block but will not be set by the reduce function. sort blocks have the same issue. This is why you should never use variables named $a or $b. There isn't really anything to fix here, although it could be mentioned in the docs.