http://qs321.pair.com?node_id=175467

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

I am but a mere chunk of monk, and have a question. I have a subroutine that will be passing back a very large chunk of data (25K or larger). Instead of returning the entire chunk, I would like to pass back a reference to that chunk; however, that chunk is created within the subroutine.

For example:

my $ref_to_big_chunk = &get_big_chunk(8675309); print "And the big data is: "; print $$ref_to_big_chunk; sub get_big_chunk { my $jenny_tel = $_[0]; my $big_jenny = [ all work done here to make this huge ] return \$big_jenny; } ----[eof]----
Now, should I just declare a variable before I execute the sub, and then pass that reference of the variable to the sub and just mess with it from within the sub? Is the above code just dangerous in terms of $big_jenny being trashed on subroutine exit (on a very busy server)? Or lastly, am I just not seeing an easier solution to all of this?

Replies are listed 'Best First'.
Re: The danger is passing back references to local subroutines.
by thelenm (Vicar) on Jun 18, 2002 at 19:40 UTC
    Perl variables are reference-counted, and are automatically destroyed when the reference count reaches zero. Since your subroutine is returning a reference to a scalar, that scalar will not automatically be destroyed when the subroutine exits. That's because there's still a reference to it, as long as you store that reference somewhere. If you get rid of that reference (i.e., the variable where you stored the reference goes out of scope or is undefed), then the data will be destroyed.

    Update: I forgot to give a helpful reference: perlref and perlobj have some nice information on reference counting if you want to know more.

    -- Mike

    --
    just,my${.02}

      There also is a great article by Simon Cozens over at perl.com describing closures.
      You might enjoy that one, too

      Kay

        What he has now is not a closure. It would be a closure if he used his idea of declaring the variable above and referencing it inside the sub.

        UPDATE:
        Actually, as long as he still passes by reference it's not a closure. Here's an example of what would make it a closure:

        my $ref_to_big_chunk; get_big_chunk(8675309); print "And the big data is: "; print $$ref_to_big_chunk; sub get_big_chunk { my $jenny_tel = $_[0]; my $big_jenny = [ all work done here to make this huge ] $ref_to_big_chunk = \$big_jenny; }
        Note that this is a terrible way to do it because it's no longer obvious that the get_big_chunk() sub alters $ref_to_big_chunk.