in reply to Subs: Pass references or return them?

Ok. You've asked when you should use them so I'll attempt to answer your question with a very long post.

Passing references of scalars to a sub is usually pretty silly since you can create references to them in your subroutine (this is due to the way perl builds @_). i.e.

#!/usr/bin/perl -lw use strict; my $a = 1; my $b = 2; sub swap { my @in = \( @_ ); # create our references, although pointless here ${$in[0]}^=${$in[1]};${$in[1]}^=${$in[0]};${$in[0]}^=${$in[1]}; } print "$a $b"; swap($a,$b); print "$a $b"; __DATA__ output: 1 2 2 1

Now you're probably wondering when you should pass references to a subroutine. If you wish to pass either a hash or an array with anything else (scalar, hash, array, etc) then you should usually pass it as a reference. You actually don't need to use references in the case where you wish to send a few scalars and an array or hash (as long as the scalars come before the array or hash) or in the case where you know how long each will be (although this is *VERY* easy to break). For instance:

#!/usr/bin/perl -wl use strict; my @a = qw(a b c x); my @b = qw(d e f y); my %c = qw(g h i j); my $d = "bill"; sub array_and_array { my (@z,@y) = @_; print "z: @z | y: @y"; } sub hash_and_array { my (%x,@w) = @_; local $, = $"; # just so we can print out %x print "x:",%x,"| w: @w"; } sub array_and_scalar { my (@v,$u) = @_; print "v: @v | u: ",$u?$u:""; } sub scalar_and_array { my ($t,@s) = @_; print "t: $t | s: @s"; } sub know_length_arrays { my (@r,@q); (@r[0..3],@q[0..3]) = @_; print "r: @r | q: @q"; } sub know_length_array_with_hash { my (@p,%o); (@p[0..3],%o) = @_; local $, = $"; print "p: @p | o:",%o; } array_and_array(@a,@b); hash_and_array(%c,@a); array_and_scalar(@a,$d); scalar_and_array($d,@a); know_length(@a,@b); know_length_array_with_hash(@a,%c); __DATA__ output: z: a b c x d e f y | y: x: c x a b g h i j | w: v: a b c x bill | u: t: bill | s: a b c x r: a b c x | q: d e f y p: a b c x | o: g h i j

When should you return references? Again, if you're dealing with multiple return types, the same rules apply.

Please note that readability is also enormously important. Even though I've presented ways of deconstructing @_ in a subroutine does not mean it's a good idea to use them. Passing references is the standard way of passing arrays and hashes to a subroutine. Please check out perlref and perlreftut as well as other material listed in perltoc for more information.

Sorry for the rant. Hope this helps.

antirice    
The first rule of Perl club is - use Perl
The
ith rule of Perl club is - follow rule i - 1 for i > 1

Replies are listed 'Best First'.
Re: Re: Subs: Pass references or return them?
by knexus (Hermit) on Sep 04, 2003 at 12:45 UTC
    Thank you for taking the time to put that post together, I really do appreciate the detail (aka rant) and it helps.

    I have looked at the perldoc stuff and I get good information there. However, being new to perl (a couple weeks-ish) I still get lost in the details trying to find somewhat of a "specific" answer to a somewhat "general" question, if that makes any sense. ;-)

    Anyhow, I usually can find the answers to "mechanical" type questions on my own. You know, "How do you do that?" etc. Where I find it more difficult is finding answers to "Why" or "When" I should (or should not) do something a particular way... the questions often best answered by experince.

    That's where I have, in particular, found this board extremely helpful and remarkably responsive. No sucking up here, that's just the way I see it!

    Thanks