Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

how internally $#array is working in Perl

by kiruthika.bkite (Scribe)
on Aug 13, 2010 at 05:11 UTC ( #854826=perlquestion: print w/replies, xml ) Need Help??
kiruthika.bkite has asked for the wisdom of the Perl Monks concerning the following question:

Using $#array we can find the last index of an array.

but when I changed the value of $[ variable ( first index of an array), the value of $#array get changed as $[ variable value + last index of an array.

So Please explain me about how $#array is internally working.
Thanks in advance.
  • Comment on how internally $#array is working in Perl

Replies are listed 'Best First'.
Re: how internally $#array is working in Perl
by sflitman (Hermit) on Aug 13, 2010 at 05:44 UTC
    My understanding is that $#x is the n-1 index for a 0-based array. All Perl arrays are 0-based, until you change $[. Why do you wish to change $[? Also, it may be safer to use scalar(@x) for how many elements there are in x. There are ominous warnings about $# going away at some point in several of the perldocs.

    As for the actual internals, you would need to look at the Perl source. (shiver) --> perlguts


      $#array is the index of the last element in the array. Perl obviously knows how many elements there are in an array - if it didn't, then it wouldn't be able to automagically grow the array as you add more stuff to it and you'd have to handle memory allocation yourself. And perl obviously knows the index of the first element, which is the value in $[. Knowing how big the array is and the starting index, calculating the last index is trivial.

Re: how internally $#array is working in Perl
by JavaFan (Canon) on Aug 13, 2010 at 08:23 UTC
    Please explain me about how $#array is internally working.
    Not much magic going on. Internally, an array is represented by an AV structure (a C struct). The first field points to an xpvav structure (another C struct). Here, the second field, called FILL, is an integer holding the current size of the array.

    The size of the array, plus the value of $[ is enough to calculate the size of $#array.

    Illustrated details.

      Actually, because $#array can be used as an lvalue, a fair bit of magic is going on (including adding "magic" to both the returned scalar and the array in some circumstances). Fortunately, it is invisible to the user.
Re: how internally $#array is working in Perl
by suhailck (Friar) on Aug 13, 2010 at 05:52 UTC
    perl -le '@arr=qw(10 1 2 3 4);$[=3;print $arr[$_],"\t",$_ for 0 .. $#a +rr;' 10 0 3 1 4 2 10 3 1 4 2 5 3 6 4 7
    How is $arr[0]=10, $arr[1]=3, and $arr[2]=4 in the above code with $[=3?
      From perlvar:
      $[ The index of the first element in an array, and of the first character + in a substring. Default is 0, but you could theoretically set it to 1 to ma +ke Perl behave more like awk (or Fortran) when subscripting and when evaluatin +g the index() and substr() functions. (Mnemonic: [ begins subscripts.) As of release 5 of Perl, assignment to $[ is treated as a compiler dir +ective, and cannot influence the behavior of any other file. (That's why you can o +nly assign compile-time constants to it.) Its use is deprecated, and by default w +ill trigger a warning. Note that, unlike other compile-time directives (such as strict), assi +gnment to $[ can be seen from outer lexical scopes in the same file. However, yo +u can use local() on it to strictly bind its value to a lexical block.
      I suspect you can assign 1 to it, but other values are silently ignored. I tried your code with $[=1, and lo and behold:
      perl -le '@arr=qw(10 1 2 3 4);$[=1;print $arr[$_],"\t",$_ for 0 .. $#a +rr;' 10 0 10 1 1 2 2 3 3 4 4 5


        I suspect you can assign 1 to it, but other values are silently ignored

        You suspect incorrectly.

        $ perl -e '@array=(qw(ant bat cat)); $[ = 94; print $array[95]."\n"' bat $ perl -e '@array=(qw(ant bat cat)); $[ = -9; print $array[-8]."\n"' bat

        How internally array holds the value like this way.I have checked the code by using Dumper function in Data::Dumper module.
        In that, it printed only 10,1,2,3,4 but when I loop through the array.It printed 6 values as 10,10,1,2,3,4.Explain me how it works?
        Thanks in advance

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://854826]
Approved by sflitman
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (3)
As of 2018-03-24 01:29 GMT
Find Nodes?
    Voting Booth?
    When I think of a mole I think of:

    Results (297 votes). Check out past polls.