in reply to Perl Riddle
our creates a lexical scoped alias of a package variable. Using it a BEGIN block does create the package global at compile time, and not much more. Your use of strict in the BEGIN block enforces strictness just there, not outside that block.BEGIN { our %ENGINES; } use strict; each %ENGINES; __END__ Global symbol "%ENGINES" requires explicit package name at - line 5. Execution of - aborted due to compilation errors.
You are calling list_engines(), which uses each on %ENGINES from set_engine while iterating over %ENGINES with each. Very bad idea, because the hash iterator is bound to each hash, not to the scope each occurs in.
my %hash; @hash{a..f} = 10..15; sub a { my $a_count; while( my ($k,$v) = each %hash) { print "$k => $v\n"; $a_count++; } $a_count++; } sub b { my $b_count; while( my ($k,$v) = each %hash) { $b_count++; print "$k => $v ($b_count out of ", a(), ")\n"; } } b() __END__ c => 12 a => 10 b => 11 d => 13 f => 15 e => 14 (1 out of 5) c => 12 a => 10 b => 11 d => 13 f => 15 e => 14 (2 out of 5) c => 12 a => 10 b => 11 d => 13 f => 15 e => 14 (3 out of 5) ...
This code runs until it hits an integer overflow on $b_count in sub b { }, because the each in sub a { } goes on iterating the same hash from where the pointer was set in sub b(), and thus $a_count is set to 5, not to 6. The hash iteration is through at the end of that while loop, so the iterator is reset. Then the print in sub b() happens, and the iteration starts over after the iterator has been reset.
You get a similar effect resetting the hash iterator with keys or values
my %hash; @hash{a..f} = 10..15; my $count; while(my ($k,$v) = each %hash) { $count++; print "$k => $v ($count of ", scalar(keys %hash),")\n"; } __END__ e => 14 (1 of 6) e => 14 (2 of 6) e => 14 (3 of 6) e => 14 (4 of 6) e => 14 (5 of 6) e => 14 (6 of 6) e => 14 (7 of 6) ... (runs forever)
so don't do that.
--shmem
_($_=" "x(1<<5)."?\n".q·/)Oo. G°\ /
/\_¯/(q /
---------------------------- \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
|
|---|