last index of array reference

Discussion in 'Perl Misc' started by Ryan Tate, Nov 13, 2003.

  1. Ryan Tate

    Ryan Tate Guest

    If I have an array @array, I can get the last index with $#array.

    What is the equivalent way to get the last index of array reference
    $array?

    I thought $#{@$array} would work, but perl coughed up "Bizarre copy of
    ARRAY in leave at /script.pl line 230."

    Haven't been able to find anything in this in Camel or Google Groups.

    Thanks for any help

    Cheers
    r
     
    Ryan Tate, Nov 13, 2003
    #1
    1. Advertising

  2. In article <bovdd1$1l57$>,
    Ryan Tate <> wrote:

    > If I have an array @array, I can get the last index with $#array.
    >
    > What is the equivalent way to get the last index of array reference
    > $array?
    >
    > I thought $#{@$array} would work, but perl coughed up "Bizarre copy of
    > ARRAY in leave at /script.pl line 230."


    works for me using perl 5.8.1

    --
    Michael Budash
     
    Michael Budash, Nov 13, 2003
    #2
    1. Advertising

  3. On Thu, 13 Nov 2003 07:55:13 +0000 Ryan Tate wrote:

    > If I have an array @array, I can get the last index with $#array.
    >
    > What is the equivalent way to get the last index of array reference
    > $array?
    >
    > I thought $#{@$array} would work, but perl coughed up "Bizarre copy of
    > ARRAY in leave at /script.pl line 230."


    Try: $#{$array}

    HTH
    Paul

    --
    $_=q{ ^4;c;14;1b:a^5;16:c^17:e^a;11;19:h^9;15:j^0:k^18:l^13
    :n^6:eek:^7:p^10:r^b;12;1a:s^2:t^3;8:u^1};s{(?<=[;^])(\d)?([\d
    abc])}{$a=$1;$2=~/([abc])/?$a*13+ord($1)%87:$1*13+$2}egx;
    for(split/:/){($a,@_)=split/[;^]/;@@[@_]=($a)x@_}print@@
     
    Paul van Eldijk, Nov 13, 2003
    #3
  4. Ryan Tate <> wrote:
    : If I have an array @array, I can get the last index with $#array.

    : What is the equivalent way to get the last index of array reference
    : $array?

    : I thought $#{@$array} would work, but perl coughed up "Bizarre copy of
    : ARRAY in leave at /script.pl line 230."

    : Haven't been able to find anything in this in Camel or Google Groups.

    Hmm. I thought, "What a cool error message!" and wanted to see what
    'use diagnostics' would say about it. So I wrote:

    #! /usr/bin/perl

    use strict;
    use warnings;
    my @a=qw(One Two Three);
    my $r = \@a;
    print "num: ", $#a, "\n";
    print "num: ", $#{@$r}, "\n";

    __END__

    Running it gets:

    $ perl foo.pl
    num: 2
    num: 2

    That looks to be working just as you expected it to, doesn't it?

    What version of Perl are you using? My 5.6.0 on Linux and 5.6.1 on Win32
    both work. 5.8.2 for Cygwin also works. Those are all I have handy
    at the moment.

    --
    Louis Erickson - - http://www.rdwarf.com/~wwonko/

    Stay away from flying saucers today.
     
    Louis Erickson, Nov 13, 2003
    #4
  5. Ryan Tate

    Anno Siegel Guest

    Michael Budash <> wrote in comp.lang.perl.misc:
    > In article <bovdd1$1l57$>,
    > Ryan Tate <> wrote:
    >
    > > If I have an array @array, I can get the last index with $#array.
    > >
    > > What is the equivalent way to get the last index of array reference
    > > $array?
    > >
    > > I thought $#{@$array} would work, but perl coughed up "Bizarre copy of
    > > ARRAY in leave at /script.pl line 230."

    >
    > works for me using perl 5.8.1


    It does, in 5.6.0 thru 5.9.0, but should it?

    The canonical form is "$#{$arrayref}", which is derived from "$#array"
    by replacing the identifier "array" with a block "{$arrayref}" which
    returns a reference (symbolic or real) to an object of the right type.

    Why it works with an array instead of an array reference is anybody's
    guess.

    Anno
     
    Anno Siegel, Nov 13, 2003
    #5
  6. Ryan Tate

    Ben Morrow Guest

    Louis Erickson <> wrote:
    > Ryan Tate <> wrote:
    > : I thought $#{@$array} would work, but perl coughed up "Bizarre copy of
    > : ARRAY in leave at /script.pl line 230."
    >
    > Hmm. I thought, "What a cool error message!" and wanted to see what
    > 'use diagnostics' would say about it. So I wrote:

    <snip>

    perldiag says it's an internal error (otherwise known as a bug in perl
    :)... rather as I suspected.

    Interestingly, $#@a fails as expected, but $#{@a} succeeds...

    Ben

    --
    If I were a butterfly I'd live for a day, / I would be free, just blowing away.
    This cruel country has driven me down / Teased me and lied, teased me and lied.
    I've only sad stories to tell to this town: / My dreams have withered and died.
    <=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=> (Kate Rusby)
     
    Ben Morrow, Nov 13, 2003
    #6
  7. Ryan Tate

    Anno Siegel Guest

    Abigail <> wrote in comp.lang.perl.misc:
    > Anno Siegel (-berlin.de) wrote on MMMDCCXXVI
    > September MCMXCIII in <URL:news:bovn7e$kku$-Berlin.DE>:
    > }} Michael Budash <> wrote in comp.lang.perl.misc:
    > }} > In article <bovdd1$1l57$>,
    > }} > Ryan Tate <> wrote:
    > }} >
    > }} > > If I have an array @array, I can get the last index with $#array.
    > }} > >
    > }} > > What is the equivalent way to get the last index of array reference
    > }} > > $array?
    > }} > >
    > }} > > I thought $#{@$array} would work, but perl coughed up "Bizarre copy of
    > }} > > ARRAY in leave at /script.pl line 230."
    > }} >
    > }} > works for me using perl 5.8.1
    > }}
    > }} It does, in 5.6.0 thru 5.9.0, but should it?
    >
    > It has always worked this way, AFAIK.


    Apparently. I never noticed.

    [...]

    > It seems to work with just $#{@array}. @{@array} doesn't give you a list
    > of elements of @array.


    No, it does what it should do: evaluate @array in scalar context, i.e.
    take its length, and access the corresponding regex capture variable $<n>
    (if symbolic references are allowed).

    Similarly, $#{ @array} "ought to" return the top index of @<n>. The
    actual behavior could be meant to be a case of DWIM, though I doubt it.
    It isn't documented, afaik, and it shouldn't be used except for obfuscation.

    Anno
     
    Anno Siegel, Nov 13, 2003
    #7
  8. Ryan Tate

    Ryan Tate Guest

    Abigail <> wrote:
    | It seems to work with just $#{@array}. @{@array} doesn't give you a list
    | of elements of @array.

    I tried a simple replication of the error with perl5.005 -e and
    couldn't immediately reproduce, so I did some digging.

    Strangely, the problem appears related to taint mode.

    Here is how I was able to reproduce the problem. This was done under
    perl5.005 and then the same behavior was reproduced under perl5.6 and
    perl5.8.

    First of all, it is not reproducable from the command line using -e
    (!), as I will show below. So I created the file test_leave_error,
    which contains (between the lines):

    ----------------
    my $arrayref=['one','two','three'];
    print foreach 0 .. $#{@$arrayref};
    ----------------

    Then I tried the following from the shell. (I have inserted two
    linebreaks to make the perl output, when there was some, stand out
    from the shell prompt):

    ----------------
    apocalypse.OCF.Berkeley.EDU [56] perl -wT test_leave_error
    Bizarre copy of ARRAY in leave at test_leave_error line 2.
    apocalypse.OCF.Berkeley.EDU [57] perl -w test_leave_error
    012
    apocalypse.OCF.Berkeley.EDU [58] perl -ewT '$arrayref=["one","two","three"];print foreach 0 .. $#{@$arrayref}'
    apocalypse.OCF.Berkeley.EDU [59] perl -ew '$arrayref=["one","two","three"];print foreach 0 .. $#{@$arrayref}'
    apocalypse.OCF.Berkeley.EDU [60] perl -e '$arrayref=["one","two","three"];print foreach 0 .. $#{@$arrayref}'
    012
    apocalypse.OCF.Berkeley.EDU [61]
    ----------------

    As you can see, the shell produced no output at all until warnings
    were turned off.

    At this point, in my code, which must run under taint mode, I have
    reverted to using ((length @$arrayref) - 1).

    Cheers
    R
     
    Ryan Tate, Nov 13, 2003
    #8
  9. Ryan Tate <> wrote:
    | At this point, in my code, which must run under taint mode, I have
    | reverted to using ((length @$arrayref) - 1).

    Erm, after re-reading the thread, I have switched to the significant
    less brain dead $#{$arrayref}, which seems to work just fine, taint or
    no. No point, I suppose, worrying why the other version works in some
    cases but not others. IIRC & FWIW, the only reason I thought to do it
    that way was I saw someone else do something like $#{1 .. 3}, which as
    it turns out itself produces interesting results.
     
    Ryan Travis Tate, Nov 13, 2003
    #9
  10. Hi,

    "Ryan Tate" <> wrote in message
    news:bovdd1$1l57$...
    > If I have an array @array, I can get the last index with $#array.
    >
    > What is the equivalent way to get the last index of array reference
    > $array?


    perl -le '$x=[0,1,2,3]; print $#$x'
    3

    HTH,

    Peter
     
    Peter Dintelmann, Nov 14, 2003
    #10
  11. Ryan Tate

    Brad Baxter Guest

    On Thu, 13 Nov 2003, Ryan Travis Tate wrote:

    > Ryan Tate <> wrote:
    > | At this point, in my code, which must run under taint mode, I have
    > | reverted to using ((length @$arrayref) - 1).
    >
    > Erm, after re-reading the thread, I have switched to the significant
    > less brain dead $#{$arrayref}, which seems to work just fine, taint or
    > no. No point, I suppose, worrying why the other version works in some
    > cases but not others. IIRC & FWIW, the only reason I thought to do it
    > that way was I saw someone else do something like $#{1 .. 3}, which as
    > it turns out itself produces interesting results.


    Or simply $#$arrayref.

    perl -le '$arrayref=[1,2,3];print $#$arrayref' prints "2"


    Perhaps beside the point:

    perl -le 'print $#{[1..3]}' prints "2"

    perl -le 'print $#{1 .. 3}' prints "-1"

    perl -le 'print $#{1}' prints "-1"

    Curious.

    I see in perldoc pervar:

    The following are equivalent:

    @whatever = ();
    $#whatever = -1;

    But I'm not sure I'm enlightened. :)

    Regards,

    Brad
     
    Brad Baxter, Nov 15, 2003
    #11
  12. On 16 Nov 2003, Abigail wrote:

    >Brad Baxter () wrote on MMMDCCXXVIII September
    >MCMXCIII in <URL:news:p>:
    >
    >:) perl -le 'print $#{1 .. 3}' prints "-1"
    >
    >Ah, a combination of *two* weirdnesses. First the $#{ARRAY} that's
    >been the subject of the thread, and secondly that 1 .. 3 under certain
    >conditions returns an array:


    Well, that's not what's happening. I expected this:

    @1 = qw( two elements );
    @2 = qw( );
    @3 = qw( this has four elements );
    @{"4E0"} = qw( ah ha );

    print "$#{1 .. 4}: $_" while <DATA>;
    __DATA__
    foo
    bar
    blat
    quux

    to output:

    1: foo
    -1: bar
    3: blat
    1: quux

    Because the $#{1 .. 4} is the scalar flip-flop, and it's equivalent to
    $#{($. == 1) .. ($. == 4)}. The last time that's true, of course, it
    returns the value of $. with "E0" appended to it.

    --
    Jeff Pinyan RPI Acacia Brother #734 2003 Rush Chairman
    "And I vos head of Gestapo for ten | Michael Palin (as Heinrich Bimmler)
    years. Ah! Five years! Nein! No! | in: The North Minehead Bye-Election
    Oh. Was NOT head of Gestapo AT ALL!" | (Monty Python's Flying Circus)
     
    Jeff 'japhy' Pinyan, Nov 17, 2003
    #12
  13. Ryan Tate

    Brad Baxter Guest

    On Sun, 16 Nov 2003, Abigail wrote:

    > Brad Baxter () wrote on MMMDCCXXVIII September
    > MCMXCIII in <URL:news:p>:
    > :)
    > :) perl -le 'print $#{[1..3]}' prints "2"
    >
    > Expected, [1 .. 3] is a reference to an array.


    Agreed.


    > :) perl -le 'print $#{1 .. 3}' prints "-1"
    >
    > Ah, a combination of *two* weirdnesses. First the $#{ARRAY} that's
    > been the subject of the thread, and secondly that 1 .. 3 under certain
    > conditions returns an array:
    >
    > $ perl -le 'map {print ++ $_} 1, 2, 3'
    > Modification of a read-only value attempted at -e line 1.
    > $ perl -le 'map {print ++ $_} 1 .. 3'
    > 234
    > $


    Bizarre.


    > :) perl -le 'print $#{1}' prints "-1"
    >
    > perl -le '@1 = (1 .. 3); print $#{1}' prints "2"


    Cool.


    Thanks! :)

    Brad

    --
    #!/usr/local/bin/perl
    use strict;
    use warnings;

    sub AUTOLOAD{ $_ = $main::AUTOLOAD;s }
    ..+::(.+)}$1}x;m$_$?s?_?$/?:s:.+:$_$":;
    print} use subs qw;

    Just another Perl _
    Hacker am I few of mine _
    awards are many ;;_

    mine are awards few _
    many of another Just _
    I am Hacker Perl _
     
    Brad Baxter, Nov 17, 2003
    #13
  14. Ryan Tate

    Brad Baxter Guest

    On Sun, 16 Nov 2003, Jeff 'japhy' Pinyan wrote:

    > On 16 Nov 2003, Abigail wrote:
    >
    > >Brad Baxter () wrote on MMMDCCXXVIII September
    > >MCMXCIII in <URL:news:p>:
    > >
    > >:) perl -le 'print $#{1 .. 3}' prints "-1"
    > >
    > >Ah, a combination of *two* weirdnesses. First the $#{ARRAY} that's
    > >been the subject of the thread, and secondly that 1 .. 3 under certain
    > >conditions returns an array:

    >
    > Well, that's not what's happening. I expected this:
    >
    > @1 = qw( two elements );
    > @2 = qw( );
    > @3 = qw( this has four elements );
    > @{"4E0"} = qw( ah ha );
    >
    > print "$#{1 .. 4}: $_" while <DATA>;
    > __DATA__
    > foo
    > bar
    > blat
    > quux
    >
    > to output:
    >
    > 1: foo
    > -1: bar
    > 3: blat
    > 1: quux
    >
    > Because the $#{1 .. 4} is the scalar flip-flop, and it's equivalent to
    > $#{($. == 1) .. ($. == 4)}. The last time that's true, of course, it
    > returns the value of $. with "E0" appended to it.


    Holy cow. Yes, I get it now. No, I don't expect to go there.

    Regards,

    Brad
     
    Brad Baxter, Nov 17, 2003
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Knute Johnson

    Determine index from array reference?

    Knute Johnson, Jan 24, 2007, in forum: Java
    Replies:
    31
    Views:
    882
    Chris Uppal
    Jan 30, 2007
  2. Shawn W_
    Replies:
    5
    Views:
    311
    Aldric Giacomoni
    Sep 16, 2009
  3. Martin

    last index of @array

    Martin, Dec 11, 2003, in forum: Perl Misc
    Replies:
    4
    Views:
    94
    geoffroy
    Dec 14, 2003
  4. Replies:
    16
    Views:
    168
    John W. Krahn
    May 30, 2006
  5. Tomasz Chmielewski

    sorting index-15, index-9, index-110 "the human way"?

    Tomasz Chmielewski, Mar 4, 2008, in forum: Perl Misc
    Replies:
    4
    Views:
    336
    Tomasz Chmielewski
    Mar 4, 2008
Loading...

Share This Page