This is partly a question about style, maintainability, etc. and partly one about my understanding(or most probably lack there of) of scope .

Background
I am creating a sub that will take 2-3 scalars as input, munge them (sparing the originals)and return separate results to the caller in some fashion. There are many ways to go and I am looking for some advice/pro's/cons.
I wrote a silly test script at the end to illustrate options I see.

I am looking at:

1.Pass the arguments and return the results:

sub Munger1 { my ($p1, $p2) = @_; #... my $munge1 = $p1.' or '.$p2; my $munge2 = $p2.' or '.$p1; return ($munge1, $munge2); } my ($a1, $a2) = Munger1($p1, $p2);
To me this is real clear regarding not only the subs args but what it returns when looking at the call or the sub. However, since the returned strings were scoped to the sub, I would guess there is copying going on in the assignment upon return. Anyone know if this is true?

2.Pass the arguments and explicit references to args to return the results in.

sub Munger2 { my ($p1, $p2, $m1, $m2) = @_; #... $$m1 = $p1.' or '.$p2; $$m2 = $p2.' or '.$p1; } Munger2($p1, $p2, \$a3, \$a4);
This seems good too. The caller passes in where it wants the results placed. The fact that explicit refs are made clues the reader in on what's going to happen. Also, this would seem to avoid copying the results as in option 1 (assuming I am correct there).

3.Pass the arguments and "Aliased" scalar refs (if using scalars of course).

sub Munger3 { my ($p1, $p2) = @_; #... $_[2] = $p1.' or '.$p2; $_[3] = $p2.' or '.$p1; } Munger2($p1, $p2, $a5, $a6);
This is just a variation on option 2 above but it "silently" passes the "aliased" refs. The reader probably won't realize initially that $a5 and $a6 will be modified. Arggg. Also, I have read some other posts which mention this as being undesirable for a number of reasons except in certain situations. I think I'll just stay clear for now ;-)

4.Pass the arguments and return references to the results.

sub Munger4 { my ($p1, $p2) = @_; #... my $munge1 = $p1.' or '.$p2; my $munge2 = $p2.' or '.$p1; return (\$munge1, \$munge2); } my ($ar7, $ar8) = Munger4($p1, $p2);
This looks pretty good, as long as the it's made clear that the return vars are refs, presumably via good names. However, this one puzzles me bit. When the sub returns the references, the scalars it created and returned references to go out of scope, don't they? If so, then why does this seem to work? Isn't the data gone?
Or is it waiting to blow up down the road, say after a garbage collection?
I dug a bit and only found something on returning by reference and how to do it but that was all. Are there problems/caveats using this approach?

Thanks

Simple test code below:

#!/usr/bin/perl -w use strict; sub Munger1 { # Munger returns 2 scalars my ($p1, $p2) = @_; #... my $munge1 = $p1.' or '.$p2; my $munge2 = $p2.' or '.$p1; return ($munge1, $munge2); } sub Munger2 { # Munger2 returns results via passed +in references my ($p1, $p2, $m1, $m2) = @_; #... $$m1 = $p1.' or '.$p2; $$m2 = $p2.' or '.$p1; } sub Munger3 { # Munger3 returns results via "aliase +d"??? references my ($p1, $p2) = @_; #... $_[2] = $p1.' or '.$p2; $_[3] = $p2.' or '.$p1; } sub Munger4 { # Munger4 returns 2 scalar references my ($p1, $p2) = @_; #... my $munge1 = $p1.' or '.$p2; my $munge2 = $p2.' or '.$p1; return (\$munge1, \$munge2); } my $p1 = "This"; my $p2 = "That"; my ($a1, $a2) = Munger1($p1, $p2); print "Munger 1: A1=$a1 A2=$a2\n"; my ($a3, $a4) = ('a3' , 'a4'); Munger2($p1, $p2, \$a3, \$a4); print "Munger 2: A3=$a3 A4=$a4\n"; my ($a5, $a6) = ('a5' , 'a6'); Munger3($p1, $p2, $a5, $a6); print "Munger 3: A5=$a5 A6=$a6\n"; my ($aref7, $aref8) = Munger4($p1, $p2); print "Munger 4: A7=$$aref7 A8=$$aref8\n";

janitored by ybiC: balanced <readmore> tags around code chunks


In reply to Subs: Pass references or return them? by knexus

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.