http://www.perlmonks.org?node_id=559013

Some time ago I wrote a subroutine which takes a number of arrays named @out_a @out_b @out_c etc. and gets one entry at a time in parallel from a specified subset of these arrays to write into a tab-delimited line which is added to a single output array. This output array was then used to load an Excel spreadsheet using the "Import Data" function. The parameter passed to the subroutine is an array of letters which designate the names of the arrays to be used for input. The input arrays are all different lengths. (I have since changed the code to write the data directly into the spreadsheet using OLE stuff but that is not the point here.) In the process of writing this code I discovered a very subtle distinction between "my" and "local" variables which was not initially obvious to me. I don't know if this is the correct place to post this but it is not a question so I am posting it here. There are obviously a number of ways to improve the code but again the point is the subtle difference between "my" and "local".
sub meld_columns { my (@cols_to_meld) = @_; my ($ctm, $arrnm, $aline); my @outarray; # "local" needed for the following vice "my" because # the indirect references [$$ctm] require access to # the global symbol table and "my" variables are not # in the global symbol table. local ($a, $b, $c, $d, $e, $f, $g, $h); # Set column indicators all to -1 (eol) $a = $b = $c = $d = $e = $f = $g = $h = "-1"; # then set the ones we are processing to 0 foreach $ctm (@cols_to_meld) { $$ctm = 0; } while (($a >= 0)||($b >= 0)||($c >= 0)||($d >= 0)||($e >= 0)||($f +>= 0)||($g >= 0)||($h >= 0)) { $aline = ''; foreach $ctm (@cols_to_meld) { $arrnm = 'out_'."$ctm"; if (($$ctm <= $#$arrnm) && ($$ctm ne "-1")) { $aline .= "$$arrnm[$$ctm]\t"; $$ctm++; $$ctm = "-1" if ($$ctm > $#$arrnm); } else { $aline .= "\t\t"; $$ctm = "-1"; } } $aline =~ s/(.*)\t$/$1/; # get rid of trailing tab push @outarray, ("$aline"); } return @outarray; }