chayashida has asked for the wisdom of the Perl Monks concerning the following question:

I need help with my and scope. Management asked I audit someone else's code, and I came across what I thought was a problem with a variable going out of scope.

I wrote the following as a test, and to my surprise, it ran without errors! Now I'm really confused.

use strict; use warnings; sub scope_test() { my @test_array = (1, 2, 3, 4, 5, 6); return \@test_array; } print join ("\n", @{ scope_test() } );

I thought that @test_array was local to the function, so it would need to copy the data before returning a value. I thought that returning a reference to that variable would cause a problem, but it doesn't.

What's going on here? Am I crazy? Am I biased because C/C++ behaves differently with scope? Or am I complete wrong about scope in the first place, and it works this way in both Perl and C/C++? There's no style guide here, and sometimes I have a problem differentiating between "different from how I'd do it" and "wrong."

Thanks in advance for any help.

Edit: Updated the title for better search results later

Replies are listed 'Best First'.
Re: my and scope
by LanX (Saint) on Mar 28, 2013 at 20:59 UTC
    > Or am I complete wrong about scope in the first place,

    Indeed!

    By returning a reference of a scoped variable you're incrementing it's "reference-counter", such that the variable is not destroyed when leaving the scope.

    The variable will be destroyed as soon as you also delete any variable holding that reference, cause the reference counter goes to 0.

    Can't give much guidance about how C or C++ behave.

    Cheers Rolf

    ( addicted to the Perl Programming Language)

    update

    from perlref

           Hard references are smart--they keep track of reference counts for you,
           automatically freeing the thing referred to when its reference count
           goes to zero.  (Reference counts for values in self-referential or
           cyclic data structures may not go to zero without a little help; see
           "Two-Phased Garbage Collection" in perlobj for a detailed explanation.)
           If that thing happens to be an object, the object is destructed.  See
           perlobj for more about objects.  (In a sense, everything in Perl is an
           object, but we usually reserve the word for references to objects that
           have been officially "blessed" into a class package.)
    

      Hi Rolf,

      Thanks, that helps. I re-read Chapter 8 of the Camel book after my code worked, and I came across the following on page 243:

      Suppose, for example, that you create a hard reference to a lexically scoped array named @array. This hard reference, and the referent it refers to, will continue to exist even after @array goes out of scope. A referent is only destroyed when all the references to it are eliminated.

      So everyone else thinks it's good style?

      I appreciate all the quick responses.

      Chris

        Being able to return a reference safely is fundamental to Perl, and doesn't raise any style-police eyebrows. Consider DBI, where database rows are fetched as an array-ref or hash-ref. Consider JSON, where the thawed JSON data is returned as a reference to a Perl data structure.

        Since you have a C++ background, you might appreciate that Perl references are somewhat analogous to C++11's std::shared_ptr; usually safe to return, because they are referenced counted, and safe to let fall out of scope, because the reference counting also handles destruction.


        Dave

        > So everyone else thinks it's good style?

        This is pluralistic Perl and not a "benevolent dictatorship"!

        (You will always find someone arguing, because of "side effects" or whatever. ;-)

        But honestly as Davido explained, it's fundamental, if you skip these feature it's not Perl anymore.

        Cheers Rolf

        ( addicted to the Perl Programming Language)

Re: my and scope
by McA (Priest) on Mar 28, 2013 at 21:05 UTC

    Hi,

    I try to explain in my own words: In the function you declare and instatiate an array @test_array. You now have one reference on a - lets call it - perl array object. Would you have done nothing with this array, than the last variable @test_array would have gone out of scope, the reference counter on that object would drop to zero and garbage collection would free the space needed for that array object. As soon as you return a reference to that object you increased the reference counter by one. The variable @test_array goes out of scope, but a single reference is still there, which points to an object that was created in the function.

    Here an example in C:

    char* myfunc() { char* stringpointer; stringpointer = (char*) malloc(5000); if(stringpointer == NULL) { exit(1); } strcpy(stringpointer, "Hallo"); return(stringpointer); }
    You create space for an object with malloc and the variable stringpointer does have a reference on it. Then you return the address of stringpointer. The variable stringpointer itself will be removed from stack. But in the calling function you will have a reference on the object.

    To be precise: You have to differentiate between scope (what is seen where) and object instantiation and destruction. They can have the same boundaries but they need not to.

    McA

      Hi McA,

      I think you explained it perfectly. The last sentence is exactly what was confusing me, and the C example helped immensely.

      Thank you.

      Chris

Re: my and scope
by chromatic (Archbishop) on Mar 28, 2013 at 22:15 UTC

    Think of all user-visible variables in Perl as heap allocated (but don't worry about having to free them yourself). It's fine style.

Re: my and scope
by Anonymous Monk on Mar 28, 2013 at 23:49 UTC
Re: my and scope
by Anonymous Monk on Mar 28, 2013 at 20:59 UTC

    Reference counting.

    You made and returned a reference to the variable, so it will not be garbage collected until the end of the join.