Array modification rules (?)

9 views
Skip to first unread message

Larry Wall

unread,
Jan 17, 1991, 2:59:37 PM1/17/91
to
In article <29...@shamash.cdc.com> r...@svl.cdc.com writes:
: I often want to modify the array that is being used as the
: iterator for a loop within that loop. Some examples, include
:
: - Scan the argument vector and remove or add args based on
: what was specified.
: - Scan an array and remove "uninteresting" elements
:
: To be safe, I have always used a temporary array in the
: past. Is this necessary or are there well defined rules
: for adding/deleting elements from the array being used as
: the iterator within the scope of the iteration?

The iterator in a foreach merely keeps an index into the array, and has
no knowledge of any additions or deletions. In general, if you want
to modify an array, it's better either to keep track of the current
index yourself, or build a new array by shifting from the old array and
pushing onto the new. This is just about as efficient as modifying
the array in place, which entails copying blocks of pointers back and forth.

As for removing "uninteresting" elements, this is typically done with grep().
You could even do some fancy processing with foreach, undef some of the
elements of the array, and then say @foo = grep(defined, @foo).

The only way to do this stuff in awk requires the use of both indexes and
extra arrays.

: Will this become patently obvious when my copy of "The Book"
: arrives? In any event, I could not contain my curiosity any
: longer.

I don't think we mentioned that. We probably ought to have, but we
concentrated more on saying what you can do, not what you shouldn't.
Perl itself is usually pretty good about telling you what you shouldn't
do. :-)

: Assuming the rules are formalized and "intuitive" it could
: be useful for a lot of cases. I played with the following
: little piece to determine that there is some method to what
: happens.
:
: @a=split(//,"%xJaubsctd eafngohtihjekrl mPneorplq rhsatcukvewrx");
: for (@a) {splice(@a,0,1);$x .= $_;} print "$x\n";

I don't think I want to guarantee the current behavior of foreach in the
presence of array modification. There are possible ramifications with
referencing things that no longer exist. On top of which, it's not
clear to me why the above doesn't start by outputting a %.

On the other hand, it's a pretty safe bet that the behavior won't change
any time soon...

Larry

Rich Ragan

unread,
Jan 17, 1991, 1:06:44 PM1/17/91
to
I often want to modify the array that is being used as the
iterator for a loop within that loop. Some examples, include

- Scan the argument vector and remove or add args based on
what was specified.
- Scan an array and remove "uninteresting" elements

To be safe, I have always used a temporary array in the
past. Is this necessary or are there well defined rules
for adding/deleting elements from the array being used as
the iterator within the scope of the iteration?

Will this become patently obvious when my copy of "The Book"


arrives? In any event, I could not contain my curiosity any
longer.

Assuming the rules are formalized and "intuitive" it could


be useful for a lot of cases. I played with the following
little piece to determine that there is some method to what
happens.

@a=split(//,"%xJaubsctd eafngohtihjekrl mPneorplq rhsatcukvewrx");
for (@a) {splice(@a,0,1);$x .= $_;} print "$x\n";

--
Richard R. Ragan r...@svl.cdc.com (408) 496-4340
Control Data Corporation - Silicon Valley Operations
5101 Patrick Henry Drive, Santa Clara, CA 95054-1111

Reply all
Reply to author
Forward
0 new messages