in reply to RFC - FAQ for Modification of a read-only value attempted

The difference between a list and an array is often ignored...

Indeed; for never iterates over an array. for always iterates over a list.

  • Comment on Re: RFC - FAQ for Modification of a read-only value attempted

Replies are listed 'Best First'.
Re^2: RFC - FAQ for Modification of a read-only value attempted ("list"??)
by tye (Sage) on Aug 29, 2006 at 14:18 UTC
    The difference between a list and an array is often ignored...
    Indeed; for never iterates over an array. for always iterates over a list.

    What do either of those mean? Based on later replies, it seems like people are interpretting it in terms of whether or not $_ is an alias or a copy. But saying "$_ is an alias" or "$_ is a copy" actually means something clear.

    Is there some other meaning? For example, when foreach is given an array, it might make a new list of aliases to each array member and then iterate over that list, and thus not ever directly iterating through the array. Now that I think of that, it fits what you wrote quite well, but doesn't match how others interpretted it. I guess this behavior matters if you modify the array (adding or removing members) while you are in the loop and I suspect that is what foreach does.

    Is that all that you meant or are there other aspects?

    imp, what did you mean?

    - tye        

      In the first draft of this document I discussed list versus array, but decided to trim it down before posting since it was outside of my intended scope.

      In that version I referenced a post by you that provided what I thought was a nice explanation:
      Re: Differ. array and List (there is no List)

Re^2: RFC - FAQ for Modification of a read-only value attempted
by BrowserUk (Patriarch) on Aug 29, 2006 at 12:26 UTC
    Indeed; for never iterates over an array. for always iterates over a list.

    Doesn't this suggest that for iterates over the array, rather than over a list generated from the array?

    c:\test>perl -wle"@a = 'a'..'f'; for( @a) { ++$_ }; print qq[@a]" b c d e f g

    Maybe this is semantics, but I'd like to understand.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      No.
      C:\>perl -wle"my $bar = 'NN';my @foo = 'b'..'c';for ( $bar, @foo ){ ++ +$_ } print qq! $bar @foo!" NO c d C:->
Re^2: RFC - FAQ for Modification of a read-only value attempted
by imp (Priest) on Aug 29, 2006 at 12:33 UTC
    After further thought, and a little caffeine, I have to confess that I'm not sure I understand the difference in this case. Doesn't the following example show that for does iterate over the array elements?
    my @array= (1,2,3,4); for my $item (@array) { pop @array; printf "Item: %s Array: %s\n",$item,join(', ', @array); }
    Output:
    Item: 1 Array: 1, 2, 3 Item: 2 Array: 1, 2
    If for was iterating over a list that would imply that it wa s divorced from the @array object, and that modifying the @array object would not affect the loop - no?

      It does modify the elements because the elements are not copied to the list, instead, they are referenced there:

      use Devel::Peek; my @array = (1,2,3); Dump \@array; print "====\n"; foreach (@array) { Dump $_; print "----\n"; }

      Will output:

      SV = RV(0x193de54) at 0x22593c REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x226680 SV = PVAV(0x22a95c) at 0x226680 REFCNT = 2 FLAGS = (PADBUSY,PADMY) IV = 0 NV = 0 ARRAY = 0x19240d4 FILL = 2 MAX = 3 ARYLEN = 0x0 FLAGS = (REAL) Elt No. 0 SV = IV(0x1926b90) at 0x225858 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 1 Elt No. 1 SV = IV(0x1926b94) at 0x225918 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 2 Elt No. 2 SV = IV(0x1926b98) at 0x225930 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 3 ==== SV = IV(0x1926b90) at 0x225858 REFCNT = 2 FLAGS = (IOK,pIOK) IV = 1 ---- SV = IV(0x1926b94) at 0x225918 REFCNT = 2 FLAGS = (IOK,pIOK) IV = 2 ---- SV = IV(0x1926b98) at 0x225930 REFCNT = 2 FLAGS = (IOK,pIOK) IV = 3 ----

      As you can see, the IVs printed in the for loop are the same ones from the array (same pointer value) but they now have a reference count REFCNT=2

      This means that the IVs were referenced in the new list, so that's why modifying them there will also modify them in the array.

      --
      Leviathan.
      No. Example Re^3: RFC - FAQ for Modification of a read-only value attempted Also see perlsyn (RTFM is good for you):
      If any element of LIST is an lvalue, you can modify it by modifying VAR inside the loop. Conversely, if any element of LIST is NOT an lvalue, any attempt to modify that element will fail. In other words, the "foreach" loop index variable is an implicit alias for each item in the list that you're looping over.
        I have read perlsyn - foreach, and I do not feel your quotation is relevant for the example I provided. Perhaps you intended it for BrowserUk as his post dealt with the modification of the VAR lvalue.

        The relevant portion of the document for my example would be

        If any part of LIST is an array, foreach will get very confused if you add or remove elements within the loop body, for example with splice. So don't do that.
        I do not ever add or remove elements from LIST in actual code, but it serves as a possible example of iterating over an array - or perhaps an example of iterating over a lazily constructed list, as with for (1..99999999).
Re^2: RFC - FAQ for Modification of a read-only value attempted
by imp (Priest) on Aug 29, 2006 at 11:47 UTC
    Good point. I need to clarify that and iterate over a list of values in an array, versus the list of literals. Thanks.
Re^2: RFC - FAQ for Modification of a read-only value attempted
by shmem (Chancellor) on Aug 31, 2006 at 09:27 UTC

    The builtins for, map, grep, sort all operate on lists of references; same with foreach.

    If for weren't iterating over a list of references, constructs like for(sort keys %hash) would not work as expected (or as they do ;-)

    Consider this thospel code snippet

    perl -le '@a=qw(a e f c b d); $_=$i++ for sort @a; print @a' 045213

    which prints out the sequence of array indices needed to access the unsorted array elements in sorted order.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
    post 300