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

Can someone please explain what is going on in this? I am lost on how references work in this:
use strict; my @array = ('1','2','3','blue','red'); my $array_reference = \@array; &print_array($array_reference); # print 'blue' print "COLOR: $$array_reference[3]\n"; sub print_array { my $reference = shift; foreach (@$reference) { print "IN THE SUB: $_\n"; } }

Replies are listed 'Best First'.
Re: References Explanation
by broquaint (Abbot) on Jun 26, 2003 at 14:11 UTC
    my $array_reference = \@array;
    That assigns a reference to @array to $array_reference where the reference is created by putting the backslash in front of @array.
    print "COLOR: $$array_reference[3]\n";
    Dereference $array_reference (done by adding the second $ sigil) and access the 4th element.
    foreach (@$reference) { print "IN THE SUB: $_\n"; }
    Loop over the list created by the dereferenced array referenced by $reference and print out each element.

    For a good start on references and dereferencing see. tye's References quick reference and perlreftut.
    HTH

    _________
    broquaint

      Thank you to both of you for telling me how this works!
Re: References Explanation
by ctilmes (Vicar) on Jun 26, 2003 at 14:11 UTC
    You make an array @array.

    Then you make a reference to it using "\" called $array_reference.

    Then you pass that reference to a subroutine print_array().

    The subroutine dereferences the array (@$reference) and loops over the items in the array, printing them out.

    Then you dereference the 4th item (starts at 0) with $$array_reference[3]. (you can also use $array_reference->[3] which I think looks nicer).

Re: References Explanation
by xdg (Monsignor) on Jun 26, 2003 at 14:38 UTC

    Comments posted to date are on target. It might help to conceptually break apart what you're doing when you mash together things like \@ or $$ or @$. Here's your example, using {} to break things up conceptually/visually:

    #!/usr/bin/perl use strict; my @array = ('1','2','3','blue','red'); # Get an array reference (via "\@") for the array called "array" my $array_reference = \@{array}; &print_array($array_reference); # print 'blue' # lookup the fourth array element "${X}[3]" of the X defined by $array +_reference print "COLOR: ${$array_reference}[3]\n"; sub print_array { my $reference = shift; # access as an array the thing defined by $reference foreach (@{$reference}) { print "IN THE SUB: $_\n"; } }

    The $$x and @$x are shortcuts to ${$x} and @{$x} -- in short, they tell perl how you want the reference to be interpreted -- either as a scalar or an array. The funny one might seem to be $$x[], but just as you access an element of @a with $a[], the array you could get via @{$x} you can access an element of with ${$x}[].

    The tutorials suggested above are a good start for more detail

    -xdg

    Edited to fix display of [].

Re: References Explanation
by bunnyman (Hermit) on Jun 26, 2003 at 14:33 UTC

    A reference is like a pointer from C and C++, except that it will always point at something (a reference can't be null or pointing to invalid memory).

    So $array_reference is a variable which contains a pointer to the same memory as @array contains. That means that @array and @$array_reference (note the @ symbol there) are the same thing, but $array_reference (no @ symbol) is a different thing.

    When the reference is passed to the sub, a copy of it is made. This copy also points to the same memory as @array, so @$reference is still the same thing as @array. If you tried to pass @array to the sub directly, the sub would have a copy of it and it would only be able to change the copy, but not be able to change the real @array.

    You can read the tutorial for more information.

      A reference can't be null but it can reference empty strings, null characters and undefined values.

      #!/usr/bin/perl -w use strict; foreach my $ref (\'', \"\0", \undef) { print $ref, " --> ", ${$ref}, "\n"; }
      Note the warning about using an uninitialized value.

Re: References Explanation
by aquarium (Curate) on Jun 26, 2003 at 14:38 UTC
    for further reading...the last bit...the foreach loop within the named sub print_array is a closure. the effect of a closure is that it remembers values inside of a un-named sub. i.e the print statement remembers the value of $_ at the time the sub was declared. using a trick, assigning an un-named sub to a glob name allows you to generate functions and function names in a loop. you'd need to read up on it some more...as so do I. btw the & is not needed in &print_array($array_reference) as far as i can see.