Nested subs in Perl are actually global, but they bind, as a closure to the variables for the first time the parent sub is called.
Which is, I'm pretty sure, the root of his problem. | [reply] [Watch: Dir/Any] |
| [reply] [Watch: Dir/Any] |
Thanks for your prompt response
In my earlier post I gave simplified code, where actual function is explained in comment (#). Here is original code.
The output of two calls as follows:
PK_start : Sheet0 : 0, 0, 0, 0, 0
PK_end : Sheet0 : 5 : 17 : 82 : 0 : 0
PK_start : Sheet1 : 8, 21, 82, 0, 0
PK_start : Sheet2 : 0, 0, 82, 0, 0
PK_final : 0, 0, 82, 0, 0
PK_return : 0, 0, 82, 0, 0
APB2DCR_vPlan.ann.xml : 82
PK_start : Sheet0 : 0, 0, 82, 0, 0
PK_end : Sheet0 : 5 : 17 : 78 : 0 : 0
PK_start : Sheet1 : 8, 21, 78, 0, 0
PK_start : Sheet2 : 0, 0, 78, 0, 0
PK_final : 0, 0, 78, 0, 0
PK_return : 0, 0, 0, 0, 0
APB2DCR_vPlan.pass.ann.xml : 0
Please note return value of 3rd variable
sub getFuncCovSummary($) {
my ($reportFile) = @_;
my $func = 0;
my $compl = 0;
my $group = 0;
my $assert = 0;
my $ftest = 0;
my $targetSheet = "";
my $col = 0;
my $row = 0;
my $hvp_col = 0;
my $grp_col = 0;
my $ass_col = 0;
my $tst_col = 0;
my $plan_row = 0;
my $isData = 0;
my $isComment = 0;
my $mergeAcross = 0;
my $mergeDown = 0;
my @str = ();
my $parser = new XML::Parser ( Handlers => {
Start => \&hdl_start
+,
End => \&hdl_end,
Char => \&hdl_char,
Default => \&hdl_def,
Final => \&hdl_final
+,
});
$parser->parsefile( $reportFile );
# The Handlers
sub hdl_start{
my ($p, $elt, %atts) = @_;
return unless (($elt eq 'Worksheet') ||
($elt eq 'Row') ||
($elt eq 'Cell') ||
($elt eq 'Comment') ||
($elt eq 'Data') ||
($elt eq 'ss:Data'));
if ($elt eq 'Worksheet') {
if ($atts{'ss:Name'} =~ /^(\d)_/) {$targetSheet = "Sheet$1";}
print "PK_start : $targetSheet : $row, $col, $group, $assert,
+ $ftest<br>";
$row = 0;
$col = 0;
}
return unless $targetSheet eq "Sheet0";
if ($elt eq 'Row') { $row++; $col = 0;}
if ($elt eq 'Cell') {
$col = $col + 1 + $mergeAcross;
if ($atts{'ss:Index'} > 0) { $col = $atts{'ss:Index'};}
if ($atts{'ss:MergeAcross'} > 0) {$mergeAcross = $atts{'ss:Me
+rgeAcross'};}
else {$mergeAcross = 0;}
if ($atts{'ss:MergeDown'} > 0) {$mergeDown = $atts{'ss:MergeD
+own'};}
else {$mergeDown = 0;}
}
if ($elt eq 'Comment') { $isComment = 1;}
if (($elt eq 'Data') || ($elt eq 'ss:Data')) { @str = (); $isDat
+a = 1;}
}
sub hdl_end{
my ($p, $elt) = @_;
return unless $targetSheet eq "Sheet0";
return unless (($elt eq 'Comment') ||
($elt eq 'Data') ||
($elt eq 'ss:Data'));
if ($elt eq 'Comment') { $isComment = 0;}
if (($elt eq 'Data') || ($elt eq 'ss:Data')) {
if (!$isComment) {
my $p = 0;
my $str = join("", @str);
if ($str =~ /^hvp\s+plan/) { $hvp_col = $col; }
if ($str =~ /^value\w+\.Group/) { $grp_col = $col; }
if ($str =~ /^value\w+\.Assert/) { $ass_col = $col; }
if ($str =~ /^value\w+\.test/) { $tst_col = $col; }
if (($col == $hvp_col) && ($str =~ /^plan/)) { $plan_row
+= $row; }
if (($row == $plan_row) && ($col == $grp_col)) { $group =
+ sprintf("%0.f",$str*100); $p = 1;}
if (($row == $plan_row) && ($col == $ass_col)) { $assert =
+ sprintf("%0.f",$str*100); $p = 1;}
if (($row == $plan_row) && ($col == $tst_col)) { $ftest =
+ $str; $p = 1;}
if ($p) {print "PK_end : $targetSheet : $row : $col : $gro
+up : $assert : $ftest<br>";}
}
$isData = 0;
}
}
sub hdl_char {
my ($p, $str) = @_;
return unless $targetSheet eq "Sheet0";
return unless ($isData && !$isComment);
push @str, $str;
}
sub hdl_def { }
sub hdl_final {print "PK_final : $func, $compl, $group, $assert, $f
+test<br>"; }
print "PK_return : $func, $compl, $group, $assert, $ftest<br>";
return ($func, $compl, $group, $assert, $ftest);
}# getFuncCovSummary
| [reply] [Watch: Dir/Any] [d/l] |
Variable "$targetSheet" will not stay shared at - line 46.
Variable "$row" will not stay shared at - line 47.
Variable "$col" will not stay shared at - line 47.
Variable "$group" will not stay shared at - line 47.
Variable "$assert" will not stay shared at - line 47.
Variable "$ftest" will not stay shared at - line 47.
Variable "$mergeAcross" will not stay shared at - line 55.
Variable "$mergeDown" will not stay shared at - line 59.
Variable "$isComment" will not stay shared at - line 62.
Variable "@str" will not stay shared at - line 63.
Variable "$isData" will not stay shared at - line 63.
Variable "$targetSheet" will not stay shared at - line 68.
Variable "$isComment" will not stay shared at - line 73.
Variable "@str" will not stay shared at - line 77.
Variable "$hvp_col" will not stay shared at - line 78.
Variable "$col" will not stay shared at - line 78.
Variable "$grp_col" will not stay shared at - line 79.
Variable "$ass_col" will not stay shared at - line 80.
Variable "$tst_col" will not stay shared at - line 81.
Variable "$plan_row" will not stay shared at - line 82.
Variable "$row" will not stay shared at - line 82.
Variable "$group" will not stay shared at - line 83.
Variable "$assert" will not stay shared at - line 84.
Variable "$ftest" will not stay shared at - line 85.
Variable "$isData" will not stay shared at - line 88.
Variable "$targetSheet" will not stay shared at - line 94.
Variable "$isData" will not stay shared at - line 95.
Variable "$isComment" will not stay shared at - line 95.
Variable "@str" will not stay shared at - line 96.
Variable "$func" will not stay shared at - line 101.
Variable "$compl" will not stay shared at - line 101.
Variable "$group" will not stay shared at - line 101.
Variable "$assert" will not stay shared at - line 101.
Variable "$ftest" will not stay shared at - line 101.
And resolving those would go a long way to explaining the problem you describe in the OP.
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [Watch: Dir/Any] [d/l] |
use strict;
use warnings;
sub func {
my $calls = shift;
my $strange = "Call $calls";
print "In func (start): $strange\n";
sub subfunc1 {
print "In subfunc1: $strange\n";
$strange .= " even";
}
sub subfunc2 {
print "In subfunc2: $strange\n";
}
subfunc1();
subfunc2();
print "In func (end): $strange\n";
}
func(1);
func(2);
func(3);
func(4);
which creates the following output (including a couple of warnings!):
Variable "$strange" will not stay shared at closure2.pl line 10.
Variable "$strange" will not stay shared at closure2.pl line 15.
In func (start): Call 1
In subfunc1: Call 1
In subfunc2: Call 1 even
In func (end): Call 1 even
In func (start): Call 2
In subfunc1: Call 1 even
In subfunc2: Call 1 even even
In func (end): Call 2
In func (start): Call 3
In subfunc1: Call 1 even even
In subfunc2: Call 1 even even even
In func (end): Call 3
In func (start): Call 4
In subfunc1: Call 1 even even even
In subfunc2: Call 1 even even even even
In func (end): Call 4
which clearly demonstrates that the variable $strange in the subfuncs is decoupled from $strange in func in the second and subsequent calls to func. The warnings also tell the same story.
UPDATE: Compare to the following:
use strict;
use warnings;
my $strange;
sub subfunc1 {
print "In subfunc1: $strange\n";
$strange .= " even";
}
sub subfunc2 {
print "In subfunc2: $strange\n";
}
sub func {
my $calls = shift;
$strange = "Call $calls";
print "In func (start): $strange\n";
subfunc1();
subfunc2();
print "In func (end): $strange\n";
}
func(1);
func(2);
func(3);
func(4);
whose output is probably what you expected. Whether or not this is good style is a diffent question ...
| [reply] [Watch: Dir/Any] [d/l] [select] |