in reply to Putting weird things into $#array

Consider:

my @a = qw( 1 2 3 ); print $#a + 1, $/; my $a = \@a; print $a + 1, $/;

Replies are listed 'Best First'.
Re^2: Putting weird things into $#array
by ikegami (Patriarch) on Mar 07, 2005 at 22:04 UTC

    I don't see anything wrong. It prints what I expected.

    my @a = qw( 1 2 3 ); print $#a + 1, $/; # 3 my $a = \@a; print $a + 1, $/; # 27993901 print $#$a + 1, $/; # 3 print $a, $/; # ARRAY(0x1ab272c) printf "0x%x == %d$/", $a, $a; # 0x1ab272c == 27993900
    This is perl, v5.6.1 built for MSWin32-x86-multi-thread
Re^2: Putting weird things into $#array
by blokhead (Monsignor) on Mar 07, 2005 at 21:58 UTC
    I'm well aware that a reference in numeric context is a very large number. I also understand that setting $#a to a reference makes @a really really big. That doesn't explain why $#a is behaving so oddly when I retrieve its value.

    I would expect

    $#a = $foo; $#a = $foo + 0;
    to be the same thing. Just like how
    $hash{$foo} = 1; $hash{"".$foo} = 1;
    is the same (unless %hash is tied). But this is not the case -- when $foo is a reference and I retrieve $#a, it is also acting much like (but not entirely like) a reference, not just a number.

    blokhead

      That doesn't explain why $#a is behaving so oddly when I retrieve its value.

      When you set $#a, Perl needs an integer. If you give it something that's more than just an integer, it takes out the integer part and stores that in the appropriate place in the data structure it uses to represent the array. It throws out the rest of the information, as it doesn't need it.

      When you read $#a, Perl looks in the underlying data structure and fetches the integer stored there. It returns it. It can't return any more information. It doesn't store it.

      This is C-level stuff. If you're curious, see av.h, specifically the xpvav struct declaration and the xav_fill member. It holds an integer (see uconfig.h, I think), not an SV.

      Update: I did misread the question. The right code to read is that of the av2arylen opcode in pp.c, which I really don't follow. Consider this program though, which shows that $#a isn't a plain integer, it's an SV with magic:

      use Devel::Peek; my @a; Dump( $#a ); my $b = {foo=>1}; exit if $b + 0 > 0x10125000; $#a=$b; Dump( $#a );
        Did you read his whole post? It looks like he's demonstrating that what you're saying isn't correct. If it was, how does this work:

        % perl -le '$b={foo=>1}; $#a=$b; print keys %{$#a}' foo

        If you're right and the $# slot is just an int then how did keys get a hash out of it?

        -sam

        fetches the integer stored there. It returns it. It can't return any more information. It doesn't store it.
        Then how is it possible that in my examples, $#a is being (successfully) used a hard reference? Or am I misinterpreting the results?

        blokhead

Re: Putting weird things into $#array
by jonadab (Parson) on Mar 07, 2005 at 21:54 UTC
    I'm not sure whether to be impressed or freightened.
      You can't be freightened unless you are first palletized (and preferably shrink-wrapped if you have a tendency to flop about).

      ;-)