Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Is it possible to do pass by reference in Perl?

( #6758=categorized question: print w/ replies, xml ) Need Help??
Contributed by Anonymous Monk on Apr 04, 2000 at 01:06 UTC
Q&A  > subroutines


Answer: Is it possible to do pass by reference in Perl
contributed by chromatic

Prepending a variable with a backslash (\) creates a reference:

my $scalar = "this is a scalar"; my @array = qw( this is my array ); my %hash = ( 'this' => 'my', 'hash' => 'mine',); print_all(\$scalar, \@array, \%hash); sub print_all { my $scalar_ref = shift; my $arr_ref = shift; my $hash_ref = shift; print "Scalar: ", $$scalar_ref, "\n"; print "Array: ", join ' ', @$arr_ref, "\n"; print "Hash: ", each %$hash_ref, "\n"; }
See perlman:perlref for the juicy details.
Answer: Is it possible to do pass by reference in Perl?
contributed by Russ

One might argue that Perl always does Pass-By-Reference, but protects us from ourselves.

@_ holds the arguments passed to a subroutine, and it is common idiom to see something like:

sub mySub{ my $Arg = shift; } sub mySub2{ my ($Arg) = @_; }
Why is that? Why don't we just use the @_ array directly?

First, there is the laudable goal of more readable code, which is sufficient reason, in itself, to rename variables away from cryptic things like $_[3]. But really, we copy values out of @_ because (from the man page) "its elements are aliases for the actual scalar parameters."

In short, this means that if you modify an element of @_ in your subroutine, you are also modifying the original argument. This is almost never the expected behavior! Further, if the argument is not updatable (like a literal value, or a constant), your program will die with an error like "Modification of a read-only value attempted."

Consider:

sub test{ $_[0] = 'New Value'; } my $Var = 'Hi there'; print "$Var\n"; test ($Var); print "$Var\n";
will print out:
Hi there New Value
So, yes, you can do pass-by-reference in Perl, even without backslashes; but it is almost always better (some would leave out the "almost" in this statement) to make your caller explicitly pass you a reference if you intend to modify a value.
Answer: Is it possible to do pass by reference in Perl
contributed by btrott

... And, as would follow from chromatic's answer, if you modify the references within a subroutine, you'll also modify the values those references point to, outside the subroutine.

my $str = "foo"; print $str, "\n"; change(\$str); print $str, "\n"; sub change { my $ref = shift; $$ref = "bar"; }
Answer: Is it possible to do pass by reference in Perl?
contributed by tilly

In addition to the answers above it is possible to pass arrays and hashes by reference without using a \. The way to do this is to define a function with a prototype as explained in perlsub.

For a more complete explanation I can recommend FMTYEWTK About Prototypes, which says in detail what they are, where they are buggy, and the various design flaws that make them something to avoid on the whole.

Answer: Is it possible to do pass by reference in Perl?
contributed by bradcathey

In fact, passing by reference is a must to preserve the values in separate data structures, even an array and scalar. For instance:

my @array = qw ( 1 2 3 4 5 ); my $num = 6; &testsub ( @array, $num ); sub testsub { my ( @list, $single ) = @_; print @list; }
will print:
123456
Passing those values via the @_ flattens all values into one long list. However:
my @array = qw ( 1 2 3 4 5 ); my $num = 6; &testsub ( \@array, $num ); sub testsub { my ( $list, $single ) = @_; print @$list; }
will print:
12345
where passing the array by ref will keep the values from all merging into the single list.
Answer: Is it possible to do pass by reference in Perl?
contributed by RedDragon

It is possible to pass by reference in perl. The argument list u get inside ur subroutine via @_ are implicit reference to values that were passed in from inside from outside.i.e. if u pass in a list of strings, inside the body of the sub,change those strings,then they will be modified outside the subroutine.

sub ted { my($add,$sub,$mul) = @_; ... .. }

Please (register and) log in if you wish to add an answer



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • 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, 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, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            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.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others having an uproarious good time at the Monastery: (8)
    As of 2014-11-27 07:07 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      My preferred Perl binaries come from:














      Results (180 votes), past polls