Package: perl Version: 5.24.1-3+deb9u5 Severity: normal I was trying to make program below as simple as possible, but I don't understand where is the bug introduced.
The task is to make a copy of hash such that keys in new hash are made only out of alphanumerics and underscores "_". Hashes are nested. Here is the program: #!/usr/bin/perl use Data::Dumper; sub hash_is_okey { ref $_[0] eq "HASH" or return 0; # for my $k (keys %{$_[0]}) { # my $v = ${$_[0]}{$k}; while (my ($k, $v) = each %{$_[0]}) { $k =~ /\A[_[:alnum:]]+\z/ or return 0; hash_ok_or_scalar($v) or return 0; } return 1; } sub hash_ok_or_scalar { return hash_is_okey($_[0]) || ! ref $_[0]; } sub make_hash_with_good_keys { my ($x) = $_[0]; hash_ok_or_scalar($x) and return $x; ref $x eq "HASH" or die; # copy hash "%{$x}" to new hash "%h" but make names good my %h; for my $k (keys %$x) { # copy "$k" to "$n", then make good name of "$n" my $n = $k =~ s/[^[:alnum:]]/_/gr; $h{$n} = make_hash_with_good_keys($$x{$k}); } return \%h; } my $original = { "top_level" => { "level down" => 123 } }; my $with_good_keys = make_hash_with_good_keys($original); print Dumper($original, $with_good_keys); and here is the result: $VAR1 = { 'top_level' => { 'level down' => 123 } }; $VAR2 = { 'top_level' => $VAR1->{'top_level'} }; In program hash "$with_good_keys" is made by: * initializing new hash "%h", and then asigning to that hash new value or * plugging reference if "subhash" has good keys. But the result is bad, because "VAR2" has bad key "level down" -- contains space. If I change this part of program: # for my $k (keys %{$_[0]}) { # my $v = ${$_[0]}{$k}; while (my ($k, $v) = each %{$_[0]}) { to look like this (uncomment "for...keys", comment "while...each"): for my $k (keys %{$_[0]}) { my $v = ${$_[0]}{$k}; # while (my ($k, $v) = each %{$_[0]}) { then result is: $VAR1 = { 'top_level' => { 'level down' => 123 } }; $VAR2 = { 'top_level' => { 'level_down' => 123 } }; Now "$VAR2" is a copy with names modified as expected. This is extremely strange, because I don't write to hash I am iterating over with "while...each". I tried to resolve this myself for many hours, but I failed. -- System Information: Debian Release: 9.11 APT prefers oldstable-updates APT policy: (500, 'oldstable-updates'), (500, 'oldstable') Architecture: amd64 (x86_64) Kernel: Linux 4.9.0-9-amd64 (SMP w/4 CPU cores) Locale: LANG=pl_PL.UTF-8, LC_CTYPE=pl_PL.UTF-8 (charmap=UTF-8), LANGUAGE=pl_PL.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) Versions of packages perl depends on: ii dpkg 1.18.25 ii libperl5.24 5.24.1-3+deb9u5 ii perl-base 5.24.1-3+deb9u5 ii perl-modules-5.24 5.24.1-3+deb9u5 Versions of packages perl recommends: ii netbase 5.4 pn rename <none> Versions of packages perl suggests: pn libterm-readline-gnu-perl | libterm-readline-perl-perl <none> pn make <none> pn perl-doc <none> -- no debconf information