Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Does Scope of Referenced Array Matter?

by NOYB (Novice)
on Feb 19, 2012 at 22:25 UTC ( #954930=perlquestion: print w/ replies, xml ) Need Help??
NOYB has asked for the wisdom of the Perl Monks concerning the following question:

#!/usr/bin/perl A(); B(); sub A { my @array = qw(value_1 value_2); $array_ref = \@array; } sub B { foreach my $i ( @{$array_ref} ) { print "Array Value: $i \n"; } }

Since the array is declared using the 'my' keyword, could the array reference be lost if/when the array itself falls out of scope?

I know this example script functions, but is it just happenstance?

Or will the reference prevent the array itself from vaporizing when/if it falls out of scope? Or should the array be declared without using the 'my' keyword?

Thanks,

This is me. And I wouldn't lie about a thing like that. - Paraphrased from MASH dialog.

Comment on Does Scope of Referenced Array Matter?
Download Code
Re: Does Scope of Referenced Array Matter?
by Eliya (Vicar) on Feb 19, 2012 at 22:34 UTC

    A reference to the array is stored in the global (package) variable $array_ref (which itself doesn't go out of scope).  This increments the reference count of @array, so the array doesn't "vaporize" even though it is scoped lexically to the routine.

    You can use Devel::Peek to investigate the reference counts.  When you add

    Dump $array_ref;

    at the end of A(), and within B(), you'll see that the REFCNT is 2 within A(), but 1 within B()

    # Dump from within A() ... SV = PVAV(0x138f058) at 0x13b4be0 REFCNT = 2 ... # Dump from within B() ... SV = PVAV(0x138f058) at 0x13b4be0 REFCNT = 1 ...

    This is because when @array leaves its scope, the REFCNT is decremented.  If there was no reference kept to it, the REFCNT would go down to zero here, and the variable would be freed.  But due to the reference, this doesn't happen.

Re: Does Scope of Referenced Array Matter?
by tangent (Deacon) on Feb 19, 2012 at 22:37 UTC
    Your array is declared using the 'my' keyword but your $array_ref isn't, it is acting as a global variable (something you may not want). It will keep the array alive until it (the reference) goes out of scope, which in this case is when your program ends. If you use strict in your program it will tell you:
    Global symbol "$array_ref" requires explicit package name
Re: Does Scope of Referenced Array Matter?
by CountZero (Bishop) on Feb 19, 2012 at 22:47 UTC
    Try this:
    sub a_sub { my @array = qw /a b c d e f g/; $ref = \@array; } a_sub(); print "$ref - @$ref - @array";
    Output:
    ARRAY(0x9dbb04) - a b c d e f g - 
    The @array does not evaporate, although it can no longer be reached outside of the scope of its enclosing sub by using its lexical name. Actually the @array in the print statement has nothing to do with the @array in the sub.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

    My blog: Imperial Deltronics
Re: Does Scope of Referenced Array Matter?
by Anonymous Monk on Feb 19, 2012 at 23:15 UTC
Re: Does Scope of Referenced Array Matter?
by NOYB (Novice) on Feb 19, 2012 at 23:59 UTC
    Thanks all for your very nice and well explained replies.
Re: Does Scope of Referenced Array Matter?
by ikegami (Pope) on Feb 20, 2012 at 09:23 UTC

    "my" allocates a new variable, so what you're doing is completely safe.

    (Optimisations normally cause the variable to be reused, but they are specifically disabled when a reference escapes the scope like here.)

    Well, the needless use of a global variable probably isn't that safe. Return the reference instead.

    use strict; # Always! use warnings; # Always! B(A()); sub A { my @array = qw(value_1 value_2); return \@array; } sub B { my ($array_ref) = @_; foreach my $i ( @{$array_ref} ) { print "Array Value: $i \n"; } }
Re: Does Scope of Referenced Array Matter?
by repellent (Priest) on Feb 20, 2012 at 22:22 UTC
    It may be interesting to note how reference count grows. Here's an example of reference counts to the scalar $a, with explanation in comments:
    use Devel::Peek qw(SvREFCNT); my $a = 9; # 1 = $a is an SV of an IV with refcnt of + 1 warn SvREFCNT($a), "\n"; my $b = \$a; # 2 = (anonymous) scalar ref maintained b +y $b warn SvREFCNT($a), "\n"; my $d = my $c = $b; # 4 = two more ref copies made warn SvREFCNT($a), "\n"; my $f = my $e = \$b; # 4 = $a unaffected by references _to_ $b warn SvREFCNT($a), "\n"; my $g = [ $a ]; # 4 = copy of value $a in array warn SvREFCNT($a), "\n"; my $h = [ $c ]; # 5 = copy of ref to $a in array warn SvREFCNT($a), "\n"; my $i = sub { $b, $c, $e }; # 5 = $a unaffected by closure over _refs +_ to $a warn SvREFCNT($a), "\n"; my $j = sub { $a, $a, $a }; # 6 = closure over actual lexical $a warn SvREFCNT($a), "\n"; undef $_ for $b, $c, $d, $h, $j; # 1 = kill all refcnt contributors ( +except for $a itelf) warn SvREFCNT($a), "\n";

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://954930]
Approved by Corion
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (5)
As of 2014-08-21 03:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (127 votes), past polls