for my $name (@colors) { no strict 'refs'; # allow symbol table manipulation *$name = sub { "@_" }; } #### use strict; use warnings; # declaration of $name # pick one and comment out the other my $name; #our $name; # why is red printing out red rather than violet since # $name is always changing? Shouldn't it be picking up the # most recent value of $name, i.e. 'violet'? my @colors = qw(red blue green yellow orange purple violet); for $name (@colors) { no strict 'refs'; # allow symbol table manipulation *$name = sub { "@_" }; } # And another oddity: when we declare our $name *both* # red and violet complain about uniinitialized values even # though we have clearly set $name inside the for loop. # No such problems when we declare $name using my. print "----- \$name is constant inside sub ------\n"; print "red: ${\(red())}\n"; print "violet: ${\(violet())}\n"; # is it because our lack of use of $name within the generated # sub caused it to be compiled as a constant? # no: here we use $name, but it *still* prints out the value # at sub definition time, rather than the current value. for $name (@colors) { no strict 'refs'; # allow symbol table manipulation no warnings 'redefine'; #ignore noise about redefinitions *$name = sub { my $sOutput = "@_"; $name = 'something wacky and wonderful'; #change the value return $sOutput; }; } # when we declare our $name red, but not violet # complains about uninitialized values. There are no # complains when we declare my $name. Hmmm... print "----- \$name given new value inside sub ------\n"; print "red: ${\(red())}\n"; print "violet: ${\(violet())}\n"; # so maybe the closure picks up the value at the time of # definition and always uses that as the initial value even # if the value changes after subdefinition? # # but if so, why do red and violet use their own last value # setting of the value of name? Didn't we just redefine the # subroutines? shouldn't they be using the value at the time # of definition? print "----- sub used inside loop that defined it ------\n"; for $name (@colors) { no strict 'refs'; # allow symbol table manipulation no warnings 'redefine'; #ignore noise about redefinitions # why isn't $name getting set to the array eleemnt value # when the array element is red or violet? # Note: it gets set properly when we declare # our $name but not when we declare my $name print "trying out $name: "; *$name = sub { my $sOutput = "@_"; $name = 'something wacky and wonderful'; #change the value return $sOutput; }; print $name->() . "\n"; } print "----- sub used outside of loop that assigned it ------\n"; print "red: ${\(red())}\n"; print "green: ${\(green())}\n"; print "violet: ${\(violet())}\n"; #### ----- $name is constant inside sub ------ red: violet: ----- $name given new value inside sub ------ red: violet: ----- sub used inside loop that defined it ------ trying out something wacky and wonderful: trying out blue: trying out green: trying out yellow: trying out orange: trying out purple: trying out something wacky and wonderful: ----- sub used outside of loop that assigned it ------ red: green: violet: #### ----- $name is constant inside sub ------ Use of uninitialized value in concatenation (.) or string at ... red: Use of uninitialized value in concatenation (.) or string at ... violet: ----- $name given new value inside sub ------ Use of uninitialized value in concatenation (.) or string at ... red: violet: ----- sub used inside loop that defined it ------ trying out red: trying out blue: trying out green: trying out yellow: trying out orange: trying out purple: trying out violet: ----- sub used outside of loop that assigned it ------ red: green: violet: