Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re^2: scope of an autovivified variable?

by rmcgowan (Sexton)
on May 11, 2011 at 20:37 UTC ( [id://904249]=note: print w/replies, xml ) Need Help??


in reply to Re: scope of an autovivified variable?
in thread scope of an autovivified variable?

OK, but I'll have to take your word regarding Devel::Peek and it's output. I have no idea what it means (for now).

What I do know is this:

#!/usr/local/bin/perl -w use strict; use Data::Dumper; sub f { my $x; print Dumper($x); $x="abc"; } f; f;

And the output is:

$VAR1 = undef; $VAR1 = undef;

Whether the storage space is deallocated or not seems to be irrelevant with respect to general use. I can't get back to the original variable the second time around. Or at least, that's what it looks like. Perhaps some additional discussion about what you mean would help my feeble understanding.

Replies are listed 'Best First'.
Re^3: scope of an autovivified variable?
by ikegami (Patriarch) on May 11, 2011 at 22:15 UTC

    Perhaps some additional discussion about what you mean would help my feeble understanding.

    You said the "data is getting carried over from one iteration of the outer loop to the next, when it wouldn't if the array were lexical."

    That's not true, because the array is lexical. Whatever you think is happening doesn't change the scope of the variable.

    I can't get back to the original variable the second time around.

    You say "variable" when you mean "value".

    Updated based on better understanding of the question.

      You're right, I meant value.

      Specifically, I don't understand what you mean by "You are mistaken in your belief that lexical variables get deallocated at the end of their scope." When a variable goes "out of scope", I thought it meant both the value it referred to and that specific variable name were no longer available to the program. Put another way:

      if($x) { my $y; ... } $y ...

      The second $y has nothing to do with the one inside the 'if'. Outside of the 'if', I have no way to get to the 'inside the if' $y or its value. At least, that was my understanding. So, I've been doing things like:

      use strict; my $c = 0; while(<>) { chomp; $c++; my $a; print "1: $a iteration $c\n" if $a; $a = $_; print "2: $a iteration $c\n" if $a; }

      And expecting that, every time around the loop, the value for $a from any prior loop would have been forgotten. Which means the first 'print' would never run. What you're saying makes me think this is not true, even though experience shows it works. Therefore, there's something about what you said that I'm not understanding.

      I'm also not at all familiar with 'Devel::Peek' and have no idea how to interpret the output you supplied, which just adds to the confusion.

        "Which means the first 'print' would never run."...Yes this is true. Your understanding of that code is correct.

        Going back to the original problem, the OP had some invalid code that Perl didn't complain about but nevertheless executed in some undefined way which produced some weird results. Those weird results caused some confusion.

        As davido points out, don't use "my" and single action "if". If you had written:

        if ($headerStr) { my @headerElements = split /\s+/, $headerStr; }
        it would have been apparent that this although legit, wouldn't work (wrong scope of @headerElements) and Perl would complain about subsequent use of @headerElements.

        If "use strict;" is not in force, it is possible to have code that generates global variables even within subroutines! Below, $a is created in the subroutine, and is visible outside of it. I presume the undefined behavior of the single action "if" caused something similar to $a to be created on your version of Perl.

        #!/usr/bin/perl -w #### NOTE: strict is not in force!! ### set_a(); print "a outside of sub is $a\n"; print "b outside of sub is $b\n"; sub set_a { $a = int(rand(100)); print "a in sub is $a\n"; my $b = int(rand(100)); print "b in sub is $b\n"; } __END__ Name "main::b" used only once: possible typo at C:\TEMP\scopedemo.pl l +ine 5. Use of uninitialized value $b in concatenation (.) or string at C:\TEM +P\scopedemo.pl line 5. a in sub is 27 b in sub is 45 a outside of sub is 27 b outside of sub is
        Every time your code hits a "my $x;" statement, Perl creates what looks to the programmer like "a brand new x" and in this case $x is undefined. If this statement has been executed before, Perl will reuse the memory if it can. Below is a case where Perl has to allocate some new memory because the memory that was used during the last execution of "my" is still in use. If you pass a reference to some "my'ed" memory out of the sub, Perl knows about that reference, assumes that somebody else is using that memory, so it allocates some new memory.
        #!/usr/bin/perl -w use strict; my $ref = getaref(); print "ref points to $$ref\n"; my $refb = getaref(); print "refb points to $$refb\n"; print "ref still points to $$ref\n"; sub getaref { my $a = int(rand(100)); print "a in sub is $a\n"; return (\$a); } __END__ a in sub is 89 ref points to 89 a in sub is 28 refb points to 28 ref still points to 89 (the memory for the value of 89 is separate from the memory of the value of 28)
        I really hope that I did not confuse you further!

      I just looked at the link supplied (static variable hack) and this looks like the root cause of my confusion.

      It will take a little time to be sure but it is a much better place to be than where I was ;)

      Many thanks for your patience and the reference.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (2)
As of 2024-04-24 16:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found