knexus has asked for the wisdom of the Perl Monks concerning the following question:
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:
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?sub Munger1 { my ($p1, $p2) = @_; #... my $munge1 = $p1.' or '.$p2; my $munge2 = $p2.' or '.$p1; return ($munge1, $munge2); } my ($a1, $a2) = Munger1($p1, $p2);
2.Pass the arguments and explicit references to args to return the results in.
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).sub Munger2 { my ($p1, $p2, $m1, $m2) = @_; #... $$m1 = $p1.' or '.$p2; $$m2 = $p2.' or '.$p1; } Munger2($p1, $p2, \$a3, \$a4);
3.Pass the arguments and "Aliased" scalar refs (if using scalars of course).
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 ;-)sub Munger3 { my ($p1, $p2) = @_; #... $_[2] = $p1.' or '.$p2; $_[3] = $p2.' or '.$p1; } Munger2($p1, $p2, $a5, $a6);
4.Pass the arguments and return references to the results.
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?sub Munger4 { my ($p1, $p2) = @_; #... my $munge1 = $p1.' or '.$p2; my $munge2 = $p2.' or '.$p1; return (\$munge1, \$munge2); } my ($ar7, $ar8) = Munger4($p1, $p2);
Thanks
#!/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
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Subs: Pass references or return them?
by davido (Cardinal) on Sep 03, 2003 at 20:53 UTC | |
by knexus (Hermit) on Sep 03, 2003 at 21:03 UTC | |
|
Re: Subs: Pass references or return them?
by antirice (Priest) on Sep 03, 2003 at 22:03 UTC | |
by knexus (Hermit) on Sep 04, 2003 at 12:45 UTC | |
|
Re: Subs: Pass references or return them?
by tcf22 (Priest) on Sep 03, 2003 at 20:58 UTC | |
|
Re: Subs: Pass references or return them?
by hmerrill (Friar) on Sep 04, 2003 at 13:37 UTC |