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

Hi Monks, I used to pass scalars into subroutine and uses the $#variable to get the length. Now I am passing them as reference as shown below. However, I ca'nt figure out how to get the length. Can anyone advice? Thanks.
my @apple = (1,2,3,4); my @pear = (5,6,7,8); &test(\@apple, \@pear); sub test () { my ($one, $two) = @_; foreach ( @{$one} ) { print "\n$_"; } print "\n========================"; foreach ( @{$two} ) { print "\n$_"; } } print "\nThere are @{$two} items in Two."; print "\n";

Replies are listed 'Best First'.
Re: Passing reference to subroutine
by ikegami (Patriarch) on Oct 03, 2008 at 06:29 UTC

    For starters, $#array doesn't return the length, but the index of the last element (one less than length).

    Dereferencing Syntax shows how simple it is to convert to using a reference. References Quick Reference goes into more detail.

    What was
    $#array
    becomes
    $#{ $ref }
    which can also be written as
    $#$ref

    And if you want the size of the array,
    @array (in scalar context)
    becomes
    @{ $ref }
    which can also be written as
    @$ref

Re: Passing reference to subroutine
by Narveson (Chaplain) on Oct 03, 2008 at 06:32 UTC

    By the time you say

    print "\nThere are @{$two} items in Two.";

    your $two has gone out of scope. Move this print statement inside the sub, and you will get

    There are 5 6 7 8 items in Two.

    which will lead you to say something like

    my $count = scalar @{$two}; print "\nThere are $count items in Two.";
Re: Passing reference to subroutine
by kubrat (Scribe) on Oct 03, 2008 at 09:02 UTC

    Try to make a habit of using strict and warnigs in all of your perl scripts. That would have revealed the out of scope error that Narveson has told you about.

    use strict; use warnings;

Re: Passing reference to subroutine
by aukjan (Friar) on Oct 03, 2008 at 06:33 UTC
    Actually $#var gives you the subscript of the last item in the list, the scalar value of @var gives you the number of elements in the list. So if you want the number of elements in a list reference, you can get it by:
    my $size = scalar @$var;
Re: Passing reference to subroutine
by Skeeve (Parson) on Oct 03, 2008 at 06:31 UTC

    $# doesn't give you the length but the last index. scalar gives the length.

    Did you try $#{$variable}?


    s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
    +.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e