dirko.van.schalkwyk has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I need a pointer to what to search for in the following issue, so I may educate myself.

Currently code run in perl 5.8.8 will return the array length ,say given a array ref $a, via $#{@{$a}} . Say @a has 3 elements, the snippet will return 2.

But when I ran the code that does this in perl 5.10.1, it returns -1 for $#{@{$a}}.

Am I going mad, or just insane?

Thank you in advance

Dirko

Replies are listed 'Best First'.
Re: Perl 5.10.1 versus 5.8.8 with $#{}
by ikegami (Patriarch) on Feb 01, 2011 at 17:58 UTC

    The contents of $#{ ... } must be an expression that returns a reference or a variable name (aka symbolic reference).

    $#{ @array } was buggy in the past — it was treated as $#{ \@array } — but it was fixed to work as documented. You were apparently relying on this bug. The correct usage is

    $#{ $ref }

    or simply.

    $#$ref

    Note the parallels:

    $array[$i] ${ $ref }[$i] (also $ref->[$i]) @array @{ $ref } $#array $#{ $ref }

    Ref:
    Dereferencing Syntax
    References Quick Reference

    But when I ran the code that does this in perl 5.10.1, it returns -1 for $#{@{$a}}.

    You should have gotten

    Can't use string ("0") as an ARRAY ref while "strict refs" in use.

    Don't hide errors. Use «use strict; use warnings;»!

Re: Perl 5.10.1 versus 5.8.8 with $#{}
by kennethk (Abbot) on Feb 01, 2011 at 17:41 UTC
    It looks to me that this is a feature that was deprecated and removed - it works in v5.8.5 built for x86_64-linux-thread-multi but fails in v5.8.9 built for MSWin32-x86-multi-thread. The usual way of achieving this is only derefencing once, using $#{$array_ref} in parallel to using $#array to get the maximum index of @array. This is discussed a little in perldsc.

    And try not to use $a or $b as variables, since they are magic variables used for sorting. See $a and $b in perlvar.

      I thank you.
Re: Perl 5.10.1 versus 5.8.8 with $#{}
by Corion (Patriarch) on Feb 01, 2011 at 17:37 UTC

    This is highly unlikely to be related to a difference between 5.10 and 5.8.8 (and also easier written as $#$a). Please reduce your code to a small, self-contained program that still exhibits the behaviour.

    Maybe if you're not using strict and $a contains a string and not a reference then @{ $a } could evaluate to 0 and that behaviour maybe changed between 5.8 and 5.10, but again, I think this is unlikely.

    Update: I was wrong - it is a change in behaviour between 5.10 and 5.8 regarding to $#{ @$foo }. Using the $#$... syntax avoids the problem.

Re: Perl 5.10.1 versus 5.8.8 with $#{}
by wind (Priest) on Feb 01, 2011 at 17:36 UTC

    First off, don't use the variables $a or $b, as those are used by the sort function.

    Secondly, observe the following code to differentiate how to obtain the last array index versus the length from an array reference.

    my $arrayref = [10,11,12,13,14,15]; print "Last Index is: " . $#$arrayref . "\n"; print "Count of arraay is: " . scalar(@$arrayref) . "\n";
    -Miller
      This is a shockingly unhelpful answer to the OP. Despite the fact that you apparently didn't (bother to) understand his question, you produced useless admonishments and code.

        I believe you that are way off base.

        The original poster was attempting to access the element count for an array reference, and I provided the proper form to do this. The code that he was using $#{ @$arrayref } will force @$arrayref to a scalar context returning the element count "3" but will then attempt to dereference that string value (throwing an error if he has use strict turned on) and return -1 as the last index of an unrecognized array. This was obviously not what he desired.

        It was certainly helpful that further contributers explained the origin of that code as taking advantage of a bug in older version of perl, but in the end what was needed was the proper form to access either the element count or the last index of an array reference, whichever it was that he wanted.

        If I'm wrong, please specify how so, as my final suggestion was no different that what was provided by others later on

        -Miller

    A reply falls below the community's threshold of quality. You may see it by logging in.