Hi Michael.

Michael Hooten wrote:
> While stepping through the code I wrote, I distinctly noted that the
> substitution on $_ did NOT affect the array and vice versa.

If you watch carefully what Perl is doing, it aliases correctly _until_
you choose to modify the array. After this the correct value from
the original 'foreach' list is used, but aliasing is no longer
meaningful
and $_ is independent of the new array. It is effectively iterating
over a temporary copy of the original array.

Looking at your first algorithm:

> --------------------FIRST TRY------------------------------
> $x=0;
> for (@dir){
>    # Remove each array element that is NOT a directory name
>    # OR remove ":\s+" from the end of dir name.
>    if ( s/^(.*):\s+$/$1/ ){
>       $dir[$x] = $_;        # substitution changes $_ but not @dir
>    } else {                 # shouldn't the substitution change both?
>       splice @dir, $x, 1;
>       $_ = $dir[$x];        # splice changes @dir but not $_
>       redo;
>    }
>    $x++;
> }


Since the assignment to $_ in your 'else' clause has no effect on the
execution, and because of your modification of the array within
the loop, the following code is equivalent:

    my $x=0;
    my @temp = @dir;
    foreach (@temp) {
        if ( $_ =~ s/^(.*):\s+$/$1/ ){
            $dir[$x] = $1;
            $x++;
        } else {
            splice @dir, $x, 1;
        }
    }

where it is obvious that you wouldn't expect @dir to change with $_.

Similarly your second try:

> --------------------SECOND TRY-----------------------------
> START: @dir = `ls mosfet* | grep ^mosfet`;
> $x=0;
> for (@dir){    # substitution now changes @dir but NOT $_
>    unless( $dir[$x] =~ s/^(.*):\s+$/$1/ ){
>       splice @dir, $x, 1;
>       $_ = $dir[$x];
>       redo;
>    }
>    $x++;
> }

is equivalent to this:

    my $x=0;
    my @temp = @dir;
    foreach (@temp) {
        unless ($dir[$x] =~ s/^(.*):\s+$/$1/) {
            splice @dir, $x, 1;
        } else {
            $x++;
        }
    }

In both cases you can see that the value of $_ is unnecessary, and
is used only in the first case as an implicit parameter to the
substitution operator. The second case may therefore be more
appropriately written as:

    my $x = 0;
    while ($x < @dir) {
        :
    }

since you are using 'foreach' only to execute the body of the loop
the correct number of times.

> If anyone insists on adding or deleting elements of an array from
> within a loop, you can ...

...expect to have problems. Remember that you are doing something
that perldoc itself explicitly says not to do. It is very unlikely that
you know better, and certainly what you are doing is unsupported.
Even if it appears that you have a work-around then it will not be
a general solution, and is likely not to withstand alterations to the
related code.

Gradu diverso, via una.

Cheers Michael, and happy Perling.

Rob




-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to