Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Re: scope of variable

by Anonymous Monk
on May 27, 2013 at 09:35 UTC ( [id://1035382]=note: print w/replies, xml ) Need Help??


in reply to scope of variable

Why are those sub definition inside another subroutine? Did you want them to be lexically scoped? If so you should check that your version of perl makes it default behavior (ie perl6, which I suppose you're actually not using), or that the feature is enabled. But in perl 5.18 this feature is experimental, and should be used with caution. If you did not want lexical scope for you subs, which they probably do not have (pushes the sub names into the current package's namespace). Actually, I'm pretty your subs are only compiled once, and not each time you enter getValue. That may have nothing to do with your problem, but since you are speaking of scoping issues ...

Replies are listed 'Best First'.
Re^2: scope of variable
by bart (Canon) on May 27, 2013 at 11:46 UTC
    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.

      Thanks, I learn something new about Perl every day. When I saw the nested subs, I thought I was looking a JavaScript for a moment! :-)

      If you spot any bugs in my solutions, it's because I've deliberately left them in as an exercise for the reader! :-)
Re^2: scope of variable
by priyo (Novice) on May 27, 2013 at 12:16 UTC
    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
      Forgot to mentioned, I have  use strict;
        Forgot to mentioned, I have use strict;

        You should also be using warnings (or -w) because then you would see:

        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.

        bart's comment on closures is exactly the reason for your problem. See this simplified example:

        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 ...

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1035382]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (5)
As of 2024-03-28 08:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found