Re: Readline using foreach and while



Ben Morrow wrote:
Quoth "szr" <szrRE@xxxxxxxxxxxxxxx>:
Ben Morrow wrote:
Quoth "szr" <szrRE@xxxxxxxxxxxxxxx>:

Actually the behaviors of "for (@ary)" and "for (@ary, ())" do seem
consistant if you really think about it. The resulting list is what
it iterates over (from the first element, to what ever *count*
is... in the former case *count* come fro mthe array, and since the
condition is checked at the start of each iteration, if the array
is added to, the count is incremented.

In the latter case, a new list is created from contents of @ary +
an empty list, which gives you a new list, which contains the
values of @ary, but is a new seperate list, and thus is not
effected by changes to @ary because it has it's own copy of @ary's
values.

OK, now explain to me why

my @ary = qw/a b c/;
print map { /c/ and push @ary, 'd'; $_ } @ary;

*doesn't* work like that :).

Actually it does. The difference is, map doesn't recheck the count
every time around like for/foreach do. If you print the contents of
@ary after the line with the map statement, it does indeed contain
'd' at the end. This behavior seems to correct, as one would likely
expect that the list map returns when it is finished to be the same
length as the one /passed/ into map at the start. If you pass a 3
element list, you should get back a 3 element list, should you not?

Absolutely not. my %h = map { $_ => 1 } qw/a b c/; is quite a common
idiom.

Well, you're still getting that many *sets* which is probably what I
should of said, or have been clearer. In that example, you get 3 set of
hash pairs resulting from the 3 element list. The point is you get
count_of_passed_list amount of something from the map, in some form or
another. How exactly it's returned is determined by the template inside
the map.

<snip>
$_ is aliased to the current array element just like in for. Again,
the only difference I see if that map doesn't recheck the count of
the passed list for each iteration.

No, you're misunderstanding the difference between a list and an
array. Evaluating an array in list context returns a list of its
elements *as they are now*;

I seem to understand it just fine. What we both said above seems to be
true. Maybe we're just misunderstanding what the other is trying to say?
:-)

under most circumstances, it returns a
list of aliases to those elements, but any changes to the order of
the elements in @ary are not propagated into the list. Consider

my @ary = qw/a b c/;
sub foo {
my @keep = map "$_", @_; # kill the aliasing

Ok @keep now contains (a, b, c)...

unshift @ary, 'h';

@ary, which comes from a scope outside this sub, now contains (h, a, b,
c)

$_[$_] .= $keep[$_] for 0..$#_;

Keep in mind $_[0] *still* points to what used to be the first element
of @ary. Remember, the aliasing isn't to the *array* but to it's
*elements*. This is because when you normally pass args to a sub (e.g.,
do_something($x, $y); ), the aliasing is with $x and $y to $_[0] and
$_[1]. Passing an array just like passing that many scalars as are
elements in the array; each individual one gets aliased to the next
sequential element of @_ in the sub's scope.

}
foo @ary;
print for @ary;

Running this (with the last line as `print "$_\n" for @ary;` for
clarity) prints:

h
aa
bb
cc

Seems the changes propgated just fine to me. You pushed 'h' to the
beginning of @ary, then you effectively iterated from
$ary[1]..$ary[$#ary].

Map is the same way in that regard; $_ is an alias to an *element*

To me, this behavior is part of what separates map from for/foreach.

It separates for (LIST) from everything else that accepts a LIST.
This is why I called it 'weird'.

I still don't see what you consider weird about it. What does it do that
you don't expect it to do?

--
szr


.



Relevant Pages

  • Re: Readline using foreach and while
    ... condition is checked at the start of each iteration, if the array is ... the line with the map statement, it does indeed contain 'd' at the end. ... passed list for each iteration. ...
    (comp.lang.perl.misc)
  • Re: Readline using foreach and while
    ... condition is checked at the start of each iteration, if the array is ... the line with the map statement, it does indeed contain 'd' at the end. ... passed list for each iteration. ... this behavior is part of what separates map from for/foreach. ...
    (comp.lang.perl.misc)
  • Re: get a column out of a 2d array
    ... array in Perl without using iteration, even if the iteration is hidden ... inside a map, foreach, or something similar. ... Stonehenge Perl Training ...
    (perl.beginners)
  • Re: Can arrays be parameters to generics
    ... may be less than 500 entrys one won't notice it that much. ... possess Set or Map to rocket, ... But sometimes an array can replace those. ... government people -- they wear both hats. ...
    (comp.lang.java.programmer)
  • Continuous iterations of fractals
    ... Like many others, I was intrigued when I first saw pictures of Julia sets and Mandelbrod sets, and I had lots of fun making generating them on a computer. ... To get a continuous time-evolution, we need the "Nth iterative root" of this map, a map f, such that: ... has as Nth root ... he either reverse-iterates a point a number of times by using the inverse iteration: ...
    (sci.physics.research)