For Programmers: Free Programming Magazines  


Home > Archive > PERL Miscellaneous > March 2008 > Readline using foreach and while









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Readline using foreach and while
Saurabh Jain

2008-03-25, 4:38 am

Hi,
Is there any difference in reading a file using a while or a
foreach in perl?

If I do :
foreach(<filehandle> ) {
my $local = <filehandle>; # I assumed I will increment the file
descriptor here
print " local $local\n";
}

But if I do :
while(<filehandle> ) {
my $local = <filehandle>; # I assumed I will increment the file
descriptor here
print " local $local\n";
}
It works fine....
Is there something wrong or some difference in the two operations? Or
am I missing something?

Thanks and Regards,
Saurabh


Small example to replicate the issue
my file name is test.pl

#!/usr/bin/perl

open (handle,"test.pl")||die "\n $0 Could not open $! \n";

my $line = <handle>;#read a line till \n or eof
print " line $line";
#foreach(<handle> ){ # Not as expected
while(<handle> ){ # Works as expected
$line =<handle>;#read a line till \n or eof

print " in side $line";
$line =<handle>;#read a line till \n or eof
print " in side $line";
$line =<handle>;#read a line till \n or eof
}
close handle;
Ben Bullock

2008-03-25, 4:38 am

On Mar 25, 4:25 pm, Saurabh Jain <hundredr...@gmail.com> wrote:
> Hi,
> Is there any difference in reading a file using a while or a
> foreach in perl?


The foreach version seems to first read the whole of the file into an
array, and then go through it line by line:

#!/usr/bin/perl
#use warnings;
use strict;
open (handle,"testangleop.pl") or die "$0 Could not open $!";

my $line = <handle>; #read a line till \n or eof
print "0 line $line";
foreach (<handle> ) { # Not as expected
#while(<handle> ){ # Works as expected
print $_;
$line =<handle>; #read a line till \n or eof
print "1 in side $line";
$line =<handle>; #read a line till \n or eof
print "2 in side $line";
$line =<handle>; #read a line till \n or eof
print "3 in side $line";
}

The while seems to increment through the loop.

See also

http://www.unix.org.ua/orelly/perl/prog3/ch02_11.htm
Gunnar Hjalmarsson

2008-03-25, 4:38 am

Saurabh Jain wrote:
> Is there any difference in reading a file using a while or a
> foreach in perl?


Yes.

foreach (<FILEHANDLE> )

reads the whole file at once, and creates a list in memory of all the
lines, so that method is inefficient and not recommended in most cases.

while (<FILEHANDLE> )

reads one line at a time.

Please study "perldoc perlsyn" for more comprehensive descriptions.

--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
John W. Krahn

2008-03-25, 8:08 am

Ben Bullock wrote:
> On Mar 25, 4:25 pm, Saurabh Jain <hundredr...@gmail.com> wrote:
>
> The foreach version seems to first read the whole of the file into an
> array, and then go through it line by line:


perldoc -q "What is the difference between a list and an array"


John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall
Jürgen Exner

2008-03-25, 8:08 am

Saurabh Jain <hundredrabh@gmail.com> wrote:
> Is there any difference in reading a file using a while or a
>foreach in perl?


Yes. Reading a file line by line works only with while. foreach reads the
whole file at once.

>If I do :
> foreach(<filehandle> ) {
> my $local = <filehandle>; # I assumed I will increment the file


You just tried to read from a file that is at EOF already.

>descriptor here
> print " local $local\n";
>}
>
>But if I do :
>while(<filehandle> ) {
> my $local = <filehandle>; # I assumed I will increment the file


You are alternating between reading one line into $_ (in the while
condition) and one line into $local. Is this what you meant to do?

>descriptor here
> print " local $local\n";
>}


>
>Small example to replicate the issue
>my file name is test.pl
>
>#!/usr/bin/perl
>
>open (handle,"test.pl")||die "\n $0 Could not open $! \n";
>
>my $line = <handle>;#read a line till \n or eof
>print " line $line";
>#foreach(<handle> ){ # Not as expected
>while(<handle> ){ # Works as expected
>$line =<handle>;#read a line till \n or eof
>
>print " in side $line";
>$line =<handle>;#read a line till \n or eof
>print " in side $line";
>$line =<handle>;#read a line till \n or eof


And here you are reading one line into $_ (in the while condition) and then
successively three lines into $line. This may make sense if you know that a
data set has a fixed format of always 4 lines. But in 99% of all cases it's
a bug.
As for the foreach version: it already slurps the whole file into a list,
therefore there is nothing left that could be read into any of the $line.

jue
Ben Bullock

2008-03-25, 7:19 pm

On Tue, 25 Mar 2008 11:59:23 +0000, John W. Krahn wrote:

> Ben Bullock wrote:


>
> perldoc -q "What is the difference between a list and an array"


Found in /usr/local/lib/perl5/5.10.0/pod/perlfaq4.pod
What is the difference between a list and an array?

An array has a changeable length. A list does not.

If I had written "the foreach version reads the whole of the file into a
list", I would have contradicted this FAQ entry, which says I can't read
things into a list, because reading things into a list would change the
list's length, and "a list does not" have a changeable length.

Ben Morrow

2008-03-25, 7:19 pm


Quoth Ben Bullock <benkasminbullock@gmail.com>:
> On Tue, 25 Mar 2008 11:59:23 +0000, John W. Krahn wrote:
>
>
> Found in /usr/local/lib/perl5/5.10.0/pod/perlfaq4.pod
> What is the difference between a list and an array?
>
> An array has a changeable length. A list does not.
>
> If I had written "the foreach version reads the whole of the file into a
> list", I would have contradicted this FAQ entry, which says I can't read
> things into a list, because reading things into a list would change the
> list's length, and "a list does not" have a changeable length.


No, you're misunderstanding. A list is immutable *after it has been
created*. Obviously you can create lists with any contents, otherwise
you would be limited to using only lists compiled into perl. foreach
accepts a list as argument and iterates over it; <> in list context
(which is the real problem here) reads the entire file, splits it on
newline (or rather $/), and returns a (newly created) list with the
results. You can't modify the list after that: for an example where you
can, see Tie::File, which reads a file into an *array* instead.

Ben

Frank Seitz

2008-03-25, 7:19 pm

Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
X-Trace: individual.net ynpHLcdBT1+64H0KGaJm5w0RlE6JZijCgzMTJyur
8yJrq2EFAr
Cancel-Lock: sha1:v8KGmMyrKVzGY7Q/VpaxZoQ2xEo=
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.5) Gecko/20041217
X-Accept-Language: de, en-us, en
In-Reply-To: <ramnb5-j0c1.ln1@osiris.mauzo.dyndns.org>
Bytes: 2112
Xref: number1.nntp.dca.giganews.com comp.lang.perl.misc:647353

Ben Morrow wrote:
> Quoth Ben Bullock <benkasminbullock@gmail.com>:

Hm. Why is this distinction relevant here?
[color=darkred]
> A list is immutable *after it has been
> created*. Obviously you can create lists with any contents, otherwise
> you would be limited to using only lists compiled into perl. foreach
> accepts a list as argument and iterates over it;


use strict;
use warnings;

my @a = qw/a b c/;
for my $v (@a) {
push @a,'d' if $v eq 'c';
print "$v\n";
}
__END__
a
b
c
d

Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel
nolo contendere

2008-03-25, 7:19 pm

On Mar 25, 1:14=A0pm, Frank Seitz <devnull4...@web.de> wrote:
> Ben Morrow wrote:
>
>
>
> Hm. Why is this distinction relevant here?
>
>
> use strict;
> use warnings;
>
> my @a =3D qw/a b c/;
> for my $v (@a) {
> =A0 =A0 push @a,'d' if $v eq 'c';
> =A0 =A0 print "$v\n";}
>
> __END__
> a
> b
> c
> d
>


http://groups.google.com/group/comp...f2ebca559578bcf
nolo contendere

2008-03-25, 7:19 pm

On Mar 25, 1:50=A0pm, nolo contendere <simon.c...@fmr.com> wrote:
> On Mar 25, 1:14=A0pm, Frank Seitz <devnull4...@web.de> wrote:
>
>
>
>
n[color=darkred]
>
>
>
>
>
>
>
> http://groups.google.com/group/comp...f2ebca559578bcf


also, see 'Perl: modifying an array in a loop'

http://blog.plover.com/prog/perl/undefined.html#3
Ben Morrow

2008-03-25, 7:19 pm


Quoth Frank Seitz <devnull4711@web.de>:
> Ben Morrow wrote:
>
> Hm. Why is this distinction relevant here?


I'm not at all sure it is, except in the 'variable vs. value' sense.

>
> use strict;
> use warnings;
>
> my @a = qw/a b c/;
> for my $v (@a) {
> push @a,'d' if $v eq 'c';
> print "$v\n";
> }


Good point. for is a little weird in this respect...

Ben

John W. Krahn

2008-03-25, 7:19 pm

Frank Seitz wrote:
> Ben Morrow wrote:
>
> Hm. Why is this distinction relevant here?
>
>
> use strict;
> use warnings;
>
> my @a = qw/a b c/;
> for my $v (@a) {


We were talking about using a *list* in a foreach loop so that should be:

for my $v ( qw/a b c/ ) {

> push @a,'d' if $v eq 'c';


You are modifying an *array*, not a list.

> print "$v\n";
> }
> __END__
> a
> b
> c
> d



John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall
szr

2008-03-25, 7:19 pm

John W. Krahn wrote:
> Ben Bullock wrote:
>
> perldoc -q "What is the difference between a list and an array"


Array is the variable type, List is the type of valve an Array
takes/holds.

> Perl isn't a toolbox, but a small machine shop where you
> can special-order certain sorts of tools at low cost and
> in short order. -- Larry Wall


Amen. I always loved this quote.

--
szr


John W. Krahn

2008-03-25, 7:19 pm

Ben Bullock wrote:
> On Tue, 25 Mar 2008 11:59:23 +0000, John W. Krahn wrote:
>
>
>
> Found in /usr/local/lib/perl5/5.10.0/pod/perlfaq4.pod
> What is the difference between a list and an array?
>
> An array has a changeable length. A list does not.
>
> If I had written "the foreach version reads the whole of the file into a
> list", I would have contradicted this FAQ entry, which says I can't read
> things into a list, because reading things into a list would change the
> list's length, and "a list does not" have a changeable length.


The FAQ entry does not contain the phrase "read things into a list".

print reverse grep /a/, readdir DIR;

In the above example, where does grep() get its list from? Is the list
that grep() returns the same length as the list it gets? Where does
reverse() get its list from, and is it the same list that grep() gets?
Where does print() get its list from, and is it the same list that
reverse() gets?


John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall
comp.llang.perl.moderated

2008-03-25, 7:19 pm

On Mar 25, 1:57 pm, "szr" <sz...@szromanMO.comVE> wrote:
> John W. Krahn wrote:
>
>
>
> Array is the variable type, List is the type of valve an Array
> takes/holds.
>


Actually, an array just holds scalars... or references which is a
special type of scalar.

An array can be populated from a list though.

--
Charles DeRykus

Ben Bullock

2008-03-25, 7:19 pm

On Mar 26, 1:37 am, Ben Morrow <b...@morrow.me.uk> wrote:
> Quoth Ben Bullock <benkasminbull...@gmail.com>:
>
>
>
>
>
>
>
>
>
> No, you're misunderstanding. A list is immutable *after it has been
> created*. Obviously you can create lists with any contents, otherwise
> you would be limited to using only lists compiled into perl. foreach
> accepts a list as argument and iterates over it; <> in list context
> (which is the real problem here) reads the entire file, splits it on
> newline (or rather $/), and returns a (newly created) list with the
> results. You can't modify the list after that: for an example where you
> can, see Tie::File, which reads a file into an *array* instead.
>
> Ben


Ben Bullock

2008-03-25, 7:19 pm

On Mar 26, 5:56 am, "John W. Krahn" <some...@example.com> wrote:

> We were talking about using a *list* in a foreach loop


You might have been, but I wasn't. I was talking about Perl reading in
data from a file.

Ben Bullock

2008-03-25, 7:19 pm

On Mar 26, 1:37 am, Ben Morrow <b...@morrow.me.uk> wrote:

> No, you're misunderstanding. A list is immutable *after it has been
> created*. Obviously you can create lists with any contents, otherwise
> you would be limited to using only lists compiled into perl.


If we can create lists, then there must be a data structures inside
Perl which represents those created lists. Let's call it the "newly-
created list" data structure. There is also a data structure for
arrays, of course.

Can you tell me the difference between the "newly-created lists" data
structure and the array data structure? Is there an example of Perl
code where we can see how the "newly-created lists" differ from
arrays? Or are these actually the same thing in practice?

> foreach
> accepts a list as argument and iterates over it; <> in list context
> (which is the real problem here) reads the entire file, splits it on
> newline (or rather $/), and returns a (newly created) list with the
> results. You can't modify the list after that


But I wasn't talking about modifying the list after that.

: for an example where you
> can, see Tie::File, which reads a file into an *array* instead.


OK:

http://perldoc.perl.org/Tie/File.html

But it says very shortly into the documentation "The file is not
loaded into memory" and "Changes to the array are reflected in the
file immediately". So your statement about "reads a file into an
array" is wrong. It is not reading the file into an array. It is
making a file appear to be an array. To read a file into an array use:

my @ary = <handle>;

Then one can loop over the array using

foreach (@ary)
Gunnar Hjalmarsson

2008-03-25, 7:19 pm

Ben Bullock wrote:
> If we can create lists, then there must be a data structures inside
> Perl which represents those created lists. Let's call it the "newly-
> created list" data structure. There is also a data structure for
> arrays, of course.
>
> Can you tell me the difference between the "newly-created lists" data
> structure and the array data structure? Is there an example of Perl
> code where we can see how the "newly-created lists" differ from
> arrays? Or are these actually the same thing in practice?


C:\home>type test.pl
use warnings;
$var1 = qw/A B C/;
print "$var1\n";
@array = qw/A B C/;
$var2 = @array;
print "$var2\n";

C:\home>perl test.pl
Useless use of a constant in void context at test.pl line 2.
Useless use of a constant in void context at test.pl line 2.
C
3

C:\home>

--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
Ben Bullock

2008-03-25, 10:11 pm

On Mar 26, 8:24 am, Gunnar Hjalmarsson <nore...@gunnar.cc> wrote:
> Ben Bullock wrote:
>
>
> C:\home>type test.pl
> use warnings;
> $var1 = qw/A B C/;
> print "$var1\n";
> @array = qw/A B C/;
> $var2 = @array;
> print "$var2\n";


Thank you for making this example, but I'm interested in the
distinction between Ben Morrow's "newly-created lists" and arrays, not
the distinction between a compile-time list and an array. Your program
is merely an example of putting a compile-time list and an array into
scalar context.
Ben Bullock

2008-03-25, 10:11 pm

On Mar 26, 6:11 am, "John W. Krahn" <some...@example.com> wrote:
> Ben Bullock wrote:
>
>
>
>
>
>
> The FAQ entry does not contain the phrase "read things into a list".


I'm extremely sorry but I really don't understand what you are talking
about. I originally wrote that "the foreach version seems to read
things into an array", then you posted the reference to the FAQ, then
I read it and tried to understand what you were saying. I assumed that
you meant that I should have written "the foreach version reads things
into a list". If that isn't what you meant, perhaps you could clarify?
Your original comment was fairly cryptic, and I spent quite a long
time trying to understand what you meant.

> print reverse grep /a/, readdir DIR;
>
> In the above example, where does grep() get its list from?


From "readdir DIR", presumably. You're not making much sense to me.
Could you please stop making cryptic comments and actually explain
what you're trying to say in a way which people who don't already know
what you are talking about can understand?



Ben Morrow

2008-03-25, 10:11 pm


Quoth Ben Bullock <benkasminbullock@gmail.com>:
> On Mar 26, 1:37 am, Ben Morrow <b...@morrow.me.uk> wrote:
>
>
> If we can create lists, then there must be a data structures inside
> Perl which represents those created lists. Let's call it the "newly-
> created list" data structure.


Let's call it 'the stack'. Lists are ephemeral in Perl: they have no
existence beyond the end of the expression they are part of (counting
sub return and the corresponding call as two parts of a single
expression). If you want to keep them you have to assign them into an
array.

> There is also a data structure for arrays, of course.


Arrays are a real data structure, allocated somewhere on the heap, with
a normal ref-counted lifetime. This is, fundamentally, the difference
between the two.

> Can you tell me the difference between the "newly-created lists" data
> structure and the array data structure? Is there an example of Perl
> code where we can see how the "newly-created lists" differ from
> arrays? Or are these actually the same thing in practice?


Apart from the boring implementation details above, lists are read-only,
even when built from read-write values:

~% perl
my @ary = qw/a b c/;
$ary[0] = "f";
my ($x, $y, $z) = qw/a b c/;
($x, $y, $z)[0] = "f";
Can't modify list slice in scalar assignment at - line 4, near ""f";"
Execution of - aborted due to compilation errors.
~%

List assignment is an exception to this, of course. The only constant in
Perl is that every rule has an exception :).

> : for an example where you
>
> OK:
>
> http://perldoc.perl.org/Tie/File.html
>
> But it says very shortly into the documentation "The file is not
> loaded into memory" and "Changes to the array are reflected in the
> file immediately". So your statement about "reads a file into an
> array" is wrong. It is not reading the file into an array. It is
> making a file appear to be an array.


Yes, of course. However, it is a closer fit to 'put this file into an
array' than @ary = <HANDLE>, because it is modifiable, and the
modifications turn up in the file just as you would expect.

> To read a file into an array use:
>
> my @ary = <handle>;


No. This reads the contents of the file into a list, and then assigns
that list to an array. The contents of the array are no longer anything
to do with the file. For instance,

my ($x, $y, $z, @foo) = <HANDLE>, qw/a b c/;

works perfectly well, or

my @random = List::Util::shuffle <HANDLE>;

> Then one can loop over the array using
>
> foreach (@ary)


Yes, if you must. However (and this was the original point), by this
time you've already read the whole file. If you're just going to process
it line-by-line that's (probably) a waste of time.

Ben

xhoster@gmail.com

2008-03-25, 10:11 pm

Ben Bullock <benkasminbullock@gmail.com> wrote:
> On Mar 26, 1:37 am, Ben Morrow <b...@morrow.me.uk> wrote:
>
>
> If we can create lists, then there must be a data structures inside
> Perl which represents those created lists.


Not necessarily. A list might exist at the Perl-programmer interface
and not at the Perl-perl interface.

> Let's call it the "newly-
> created list" data structure. There is also a data structure for
> arrays, of course.


The list 1..5 might be represented in different data structures, depending
on how it is being used.


> OK:
>
> http://perldoc.perl.org/Tie/File.html
>
> But it says very shortly into the documentation "The file is not
> loaded into memory" and "Changes to the array are reflected in the
> file immediately". So your statement about "reads a file into an
> array" is wrong.


Only if an array is defined as being something in which is "in RAM".
I don't think that that is the case in Perl. So the file can be in
an array without being in RAM. A Perl array is a set of capabilities
and a syntax for accessing those capabilities.

> It is not reading the file into an array. It is
> making a file appear to be an array.


That is just nonsense. You don't have "open" file handles, either, Perl
just makes it look they are are. For that matter, files themselves
don't exist--the OS and the FS just cooperate to make it appear that way.
Heck, OSes don't even exist, the various components of the motherboard and
hard-drives just make it seem like they do.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
szr

2008-03-26, 8:10 am

comp.llang.perl.moderated wrote:
> On Mar 25, 1:57 pm, "szr" <sz...@szromanMO.comVE> wrote:
>
> Actually, an array just holds scalars... or references which is a
> special type of scalar.


Isn't it more correct to say that an array holds a *list* of scalars? If
so, then it seems what I originally said is correct; an *array's*
*value* is a list, which contains scalars (numbers, strings, and refs.)

That is, a scalar take a number, string, or ref. An array takes a list
(which ISA collection of scalars.) And by that token I suppose one could
say a hash's value is an even numbered list (key => val pairs) of
scalars :-)

--
szr


szr

2008-03-26, 8:10 am

NNTP-Posting-Host: p0db3b1bfff000000fcd3e7f7e97e805e21624f7
762557ca3.newsdawg.com
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2900.2869
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2962
X-RFC2646: Format=Flowed; Original
Bytes: 2601
Xref: number1.nntp.dca.giganews.com comp.lang.perl.misc:647397

Ben Morrow wrote:
> Quoth Ben Bullock <benkasminbullock@gmail.com>:
>
> No, you're misunderstanding. A list is immutable *after it has been
> created*.


I think a better way of thinking about it is, a list is the literal
value used by na array, just like 123 and "abc" are literal values used
by scalars and too themselves not modifiyable.

It's like how in c and c++ you could initalize an array with a literal
value
(eg, int squares[5] = {1, 4, 9, 16, 25} )

Scalar variables are interfaces to manipulate numbers & strings.
Arrays (and Hashes**) are interfaces to manipulate Lists.



** I kind of look at the *value* of a Hash as being a (even numbered)
List, much like it is for an Array. You just access the List
differently. Arrays, by ordinals. Hashes, by key.


Comments and critisms welcome.

--
szr


szr

2008-03-26, 8:10 am

Ben Morrow wrote:
> Quoth Frank Seitz <devnull4711@web.de>:

[...]
>
> Good point. for is a little weird in this respect...


Nothing really weird about it. In that case above, it's no different
than:

for (my $i=0; $i<@a; $i++) {
my $v = $a[$i];
push @a,'d' if $v eq 'c';
print "$v\n";
}


In either case, it's going over the array, one element at a time, in
sequence, s oif you "push" something onto the end, it grows the array by
one and thus the for look keeps going.

--
szr


comp.llang.perl.moderated

2008-03-26, 8:10 am

On Mar 25, 8:57 pm, "szr" <sz...@szromanMO.comVE> wrote:
> comp.llang.perl.moderated wrote:
>
>
>
>
>
> Isn't it more correct to say that an array holds a *list* of scalars? If
> so, then it seems what I originally said is correct; an *array's*
> *value* is a list, which contains scalars (numbers, strings, and refs.)
>
> That is, a scalar take a number, string, or ref. An array takes a list
> (which ISA collection of scalars.) And by that token I suppose one could
> say a hash's value is an even numbered list (key => val pairs) of
> scalars :-)
>


A purely semantic case can be made that an array contains a list.
However, internally Perl's "list" as discussed in this thread is just
a stack where values are stored/retrieved for the very limited
lifetime of a particular statement.
So I think it'd mis-charactrize an array to say it holds a list in the
sense of a ephemeral stack of values since an array's contents live on
the heap.


--
Charles DeRykus
Ben Morrow

2008-03-26, 8:10 am


Quoth "szr" <szrRE@szromanMO.comVE>:
> comp.llang.perl.moderated wrote:
>
> Isn't it more correct to say that an array holds a *list* of scalars? If
> so, then it seems what I originally said is correct; an *array's*
> *value* is a list, which contains scalars (numbers, strings, and refs.)


Mo, it's not. For instance, an array can be spliced, which a list
can't.

Ben

nolo contendere

2008-03-26, 7:32 pm

On Mar 26, 12:33=A0am, "szr" <sz...@szromanMO.comVE> wrote:
> Ben Morrow wrote:
> [...]
>
>
>
>
> Nothing really weird about it. In that case above, it's no different
> than:
>
> for (my $i=3D0; $i<@a; $i++) {
> =A0 =A0my $v =3D $a[$i];
> =A0 =A0push @a,'d' if $v eq 'c';
> =A0 =A0print "$v\n";
>
> }
>
> In either case, it's going over the array, one element at a time, in
> sequence, s oif you "push" something onto the end, it grows the array by
> one and thus the for look keeps going.
>


I think the 'weirdness' stems from the notion that 'for' supposedly
builds up a list prior to iterating over it, as opposed to 'while'
which (with respect to filehandles at least) does not. I'm not well-
versed enough to analyze the internals of how 'for' is implemented to
understand what exactly happens if LIST is simply a list, or an array,
or part of each, or if something gets appended, prepended, spliced to
an array that is part of LIST. Based on prior threads, it appears that
the behavior varies. Since the behavior is not really consistent (and
not really documented), it can validly be labeled as 'weird'.
Ben Morrow

2008-03-26, 7:32 pm


Quoth "szr" <szrRE@szromanMO.comVE>:
> Ben Morrow wrote:
>
> Nothing really weird about it. In that case above, it's no different
> than:
>
> for (my $i=0; $i<@a; $i++) {
> my $v = $a[$i];
> push @a,'d' if $v eq 'c';
> print "$v\n";
> }


It is, though. It only works if the LIST given to for is a single array:

my @ary = qw/a b c/;
for (@ary, ()) {
push @ary, 'd' if /c/;
print;
}
__END__
a
b
c

and map doesn't work like that at all

my @ary = qw/a b c/;
map {
push @ary, 'd' if /c/;
print;
} @ary;
__END__
a
b
c

and nor do sub calls. I suspect it's actually a bug: some sort of
optimization that's leaking out, and is now of course unfixable.

Ben

szr

2008-03-26, 7:32 pm

nolo contendere wrote:
> On Mar 26, 12:33 am, "szr" <sz...@szromanMO.comVE> wrote:
>
> I think the 'weirdness' stems from the notion that 'for' supposedly
> builds up a list prior to iterating over it,


Exactly. It builds a list, when necessary (like when you
use for (<FH> ) { ... } ), unless it's alreayd there ( like
with for my $element (@array) { ... } ) and /THEN/ iterates over it.

It just keeps going until the list is expended. Adding to the array like
in the quoted examples above makes the list longer and hence the extra
iteration (since the length of the list is checked each time through the
loop.)

--
szr


szr

2008-03-26, 7:32 pm

comp.llang.perl.moderated wrote:
> On Mar 25, 8:57 pm, "szr" <sz...@szromanMO.comVE> wrote:
>
> A purely semantic case can be made that an array contains a list.
> However, internally Perl's "list" as discussed in this thread is just
> a stack where values are stored/retrieved for the very limited
> lifetime of a particular statement.
> So I think it'd mis-charactrize an array to say it holds a list in the
> sense of a ephemeral stack of values since an array's contents live on
> the heap.


Well, yes and no. If you want to talk about the internal inner workings,
yes it all lives on the heap somewhere.

However, at the surface, an array's *literal* value is a List, is it
not, just as a scalar's literal values can be 123 & "abc" ?

--
szr


nolo contendere

2008-03-26, 7:32 pm

On Mar 26, 10:19=A0am, "szr" <sz...@szromanMO.comVE> wrote:
> nolo contendere wrote:
>
>
>
>
>
>
>
>
>
> Exactly. It builds a list, when necessary (like when you
> use =A0 for (<FH> ) { ... } =A0 ), unless it's alreayd there ( like
> with =A0 for my $element (@array) { ... } =A0 ) and /THEN/ iterates over i=

t.
>
> It just keeps going until the list is expended. Adding to the array like
> in the quoted examples above makes the list longer and hence the extra
> iteration (since the length of the list is checked each time through the
> loop.)
>


Provably untrue. See Ben's example. I'll restate the concept below.

my @ary =3D qw/a b c/;
# for (@ary, ()) {
# for ( (), @ary ) {
for ( @ary ) {
push @ary, 'd' if /c/;
print;
}

=2E..

only the uncommented 'for' line prints a 'd' at the end. so what you
say MAY be true if LIST is ONLY an array.
xhoster@gmail.com

2008-03-26, 7:32 pm

"szr" <szrRE@szromanMO.comVE> wrote:

>
> Exactly. It builds a list, when necessary (like when you
> use for (<FH> ) { ... } ),


I would argue that it is not *necessary* to do that. It *could* be
special-cased to read from <FH> one line at a time rather than building
a list at the beginning, rather like the special cases that exist for
a single array, or a simple range (1..1e6). Of course, then the docs would
have to add a "so don't do that" warning on doing insane things like
reading from the file handle in side the loop or changing $/.


Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
Ben Bullock

2008-03-26, 10:40 pm

On Mar 26, 9:52 am, Ben Morrow <b...@morrow.me.uk> wrote:

>
>
> No. This reads the contents of the file into a list, and then assigns
> that list to an array. The contents of the array are no longer anything
> to do with the file.


I'm not sure what sense you're using the word "read" here but it isn't
the usual one.
If I read a book, the words go into my head, but after that if I burn
the book, then usually my head doesn't catch fire, and if I shoot
myself in the head, then the book doesn't get a bullet hole through
it.

Similarly, in my understanding of the word "read" for computers, if I
read a file into an array, I don't expect that deleting or altering
the array after the "read" statement has finished will affect the
file, and vice-versa.
szr

2008-03-27, 4:49 am

nolo contendere wrote:
> On Mar 26, 10:19 am, "szr" <sz...@szromanMO.comVE> wrote:
>
> Provably untrue. See Ben's example. I'll restate the concept below.
>
> my @ary = qw/a b c/;
> # for (@ary, ()) {
> # for ( (), @ary ) {
> for ( @ary ) {
> push @ary, 'd' if /c/;
> print;
> }
>
> ...
>
> only the uncommented 'for' line prints a 'd' at the end. so what you
> say MAY be true if LIST is ONLY an array.


Isn't that because the two commented one are two lists being combined
into a new list, and it's *that* new list that's being iterated over, so
even if you add to @ary, it doesn't change the "new list", which is just
that, a new list created at the start of the loop before iterating
begins - therefore the values of the new list are set and @ary has
nothing to do with it after the create of the "new list."

Isn't this correct?

--
szr


Peter J. Holzer

2008-03-27, 10:16 pm

On 2008-03-27 04:45, szr <szrRE@szromanMO.comVE> wrote:
> nolo contendere wrote:
>
> Isn't that because the two commented one are two lists being combined
> into a new list, and it's *that* new list that's being iterated over, so
> even if you add to @ary, it doesn't change the "new list", which is just
> that, a new list created at the start of the loop before iterating
> begins - therefore the values of the new list are set and @ary has
> nothing to do with it after the create of the "new list."


Yes. But the same should be true for

for (@ary) {
...
}

for() expects a list, the list is constructed from the elements of @ary.
If you modify @ary after the list is constructed, the list shouldn't be
affected, but it is. I think Ben Morrow is right here: This smells like
an optimization: If there is only a single array, it can be used
directly instead of creating a list from it.

hp
Peter J. Holzer

2008-03-27, 10:16 pm

On 2008-03-27 01:29, Ben Bullock <benkasminbullock@gmail.com> wrote:
> On Mar 26, 9:52 am, Ben Morrow <b...@morrow.me.uk> wrote:
>
>
> I'm not sure what sense you're using the word "read" here but it isn't
> the usual one.
> If I read a book, the words go into my head, but after that if I burn
> the book, then usually my head doesn't catch fire, and if I shoot
> myself in the head, then the book doesn't get a bullet hole through
> it.
>
> Similarly, in my understanding of the word "read" for computers, if I
> read a file into an array, I don't expect that deleting or altering
> the array after the "read" statement has finished will affect the
> file, and vice-versa.


I think Ben Morrow used the word "read" exactly in the sense you
described here.

What he was getting at is that
[color=darkred]

consists (at least conceptually) of two distinct operations:

First, the <> operator is called on handle. This reads lines from handle
and returns a list with one line per element.

Then the = operator is called which takes the list from the previous
step and assigns each element to an element of the array @ary, shrinking
or expanding @ary as needed.

The <> operator doesn't know or care what happens to the list it returns
and the = operator doesn't know or care where the list that it takes
comes from. So while the overall effect of that line is "to read a file
into an array", there is no operation which does that.

hp
szr

2008-03-28, 4:40 am

Peter J. Holzer wrote:
> On 2008-03-27 04:45, szr <szrRE@szromanMO.comVE> wrote:
>
> Yes. But the same should be true for
>
> for (@ary) {
> ...
> }
>
> for() expects a list, the list is constructed from the elements of
> @ary. If you modify @ary after the list is constructed, the list
> shouldn't be affected, but it is. I think Ben Morrow is right here:
> This smells like an optimization: If there is only a single array, it
> can be used directly instead of creating a list from it.


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.

--
szr


Ben Morrow

2008-03-28, 7:16 pm


Quoth "szr" <szrRE@szromanMO.comVE>:
>
> 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 :).

Ben

nolo contendere

2008-03-28, 7:16 pm

On Mar 27, 11:26=A0pm, "szr" <sz...@szromanMO.comVE> wrote:
> Peter J. Holzer wrote:
>
>
>
>
>
>
>
>
> 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.
>


Is this explanation based on analysis of the source implementation? or
are you just using inductive reasoning to extrapolate a general rule
from a few test cases?
szr

2008-03-28, 7:16 pm

Ben Morrow wrote:
> Quoth "szr" <szrRE@szromanMO.comVE>:
>
> 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 :).
>
> Ben


For starters, we were talking about for(LIST), not map.


perldoc -f map

map BLOCK LIST
map EXPR,LIST
Evaluates the BLOCK or EXPR for each element of LIST
[...]


It would seem map does not re-check the count of the list each time
around like for those, which sort of makes sense, as it's supposed to
eval the block/expression for "each element", which to me means each
elemt of the list originally passed to map.

"map" and "for"/"foreach" are two similar but different beasts :)

--
szr


szr

2008-03-28, 10:12 pm

Ben Morrow wrote:
> Quoth "szr" <szrRE@szromanMO.comVE>:
>
> 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? Or do you consider this to be
a bug?

However, consider:

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


__OUTPUT__
abd

$_ 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. Well, that and map returns a list :-)

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

--
szr


Ben Morrow

2008-03-28, 10:12 pm


Quoth "szr" <szrRE@szromanMO.comVE>:
> Ben Morrow wrote:
>
> 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.

<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*; 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
unshift @ary, 'h';
$_[$_] .= $keep[$_] for 0..$#_;
}
foo @ary;
print for @ary;

> 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'.

Ben

szr

2008-03-29, 7:19 pm

Ben Morrow wrote:
> Quoth "szr" <szrRE@szromanMO.comVE>:
>
> 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>
>
> 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*

>
> 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


Uri Guttman

2008-03-29, 7:19 pm

>>>>> "s" == szr <szrRE@szromanMO.comVE> writes:
[color=darkred]

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

you are still missing the picture. map can return ANY number of elements
(not sets). it executes its expression/block once for each input element
but that can generate 0-?? elements which are appended to the return
list. there are no boundaries in those elements so there are no true
sets. if you return a reference which holds stuff you can force your own
boundaries and make sets. that is also a known map idiom. map generates
a new list from input from another list. the transformation can be
anything and isn't tied to how many input elements there are.

uri

--
Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Free Perl Training --- http://perlhunter.com/college.html ---------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
szr

2008-03-29, 7:19 pm

Uri Guttman wrote:
>
> common >> idiom.
>
> s> Well, you're still getting that many *sets* which is probably
> what I s> should of said, or have been clearer. In that example, you
> get 3 set of s> hash pairs resulting from the 3 element list. The
> point is you get s> count_of_passed_list amount of something from
> the map, in some form or s> another. How exactly it's returned is
> determined by the template inside s> the map.
>
> you are still missing the picture. map can return ANY number of
> elements (not sets). it executes its expression/block once for each
> input element but that can generate 0-?? elements which are appended
> to the return list.


I understand, but still, whatever is being generated to the LHS of map,
it's done that many times are there are elements in the list on the RHS.
Is that fair to say?

> there are no boundaries in those elements so there are no true sets.


I meant "set" in a very generic way. Not in the mathematical sense, but
in the sense that you get back something that can be group of something
on the LHS by the number of elements on the RHS of map. The `map { $_ =>
1 }` example gives you that many pairs, for example.

--
szr


Uri Guttman

2008-03-29, 7:19 pm

>>>>> "s" == szr <szrRE@szromanMO.comVE> writes:
[color=darkred]

s> I understand, but still, whatever is being generated to the LHS of map,
s> it's done that many times are there are elements in the list on the RHS.
s> Is that fair to say?

no, i wouldn't say what is being generated. just what i previously said
happens. the CODE in the expression/block is executed ONCE for each
input element. then the collected list of those is returned. use the
correct terminology and you will get it easier.
[color=darkred]

s> I meant "set" in a very generic way. Not in the mathematical sense, but
s> in the sense that you get back something that can be group of something
s> on the LHS by the number of elements on the RHS of map. The `map { $_ =>
s> 1 }` example gives you that many pairs, for example.

but there are no 'pairs' in the list except by the context of assigning
the list to a hash. there is just a list of elements created by the
map. map doesn't know or care what happens to its generated list. so
calling them pairs is out of context. and as such there are no
boundaries (which pairs implies). map can generate ANY sort of list you
want. no sets or pairs or groups need to be created. a single list is
what you get and all you should care about. how you use that list is up
to the next part of the expression.

uri

--
Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Free Perl Training --- http://perlhunter.com/college.html ---------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
szr

2008-03-29, 7:19 pm

(Please use proper capitalization and such, it will make your replies
easier to read.)

Uri Guttman wrote:
>
> each >> input element but that can generate 0-?? elements which are
> appended >> to the return list.
>
> s> I understand, but still, whatever is being generated to the LHS
> of map, s> it's done that many times are there are elements in the
> list on the RHS. s> Is that fair to say?
>
> no, i wouldn't say what is being generated. just what i previously
> said happens. the CODE in the expression/block is executed ONCE for
> each input element. then the collected list of those is returned.
> use the correct terminology and you will get it easier.


Well that's basically how I understand it. In fact it seems you
basically restated the same thing in a different way. 1) the expr/block
is executed once per cycle. Yep. 2) The end result is something that is
a grouping, whether singular (say, a simple list) or more complex (like,
say, a hash key/value pair), of the same amount of elements in the input
list.

I know using proper terminology is important, but I think understand
meaning as someone put it into their own words is also an important
skill. This is something I have to do quite frequently in my line of
work when dealing with many kinds of people regarding projects I work
on. Not all of them are as savvy with programming (or a specific
language like Perl) and often I have to use simpler terms to describe
things.

> sets.
>
> s> I meant "set" in a very generic way. Not in the mathematical
> sense, but s> in the sense that you get back something that can be
> group of something s> on the LHS by the number of elements on the
> RHS of map. The `map { $_ => s> 1 }` example gives you that many
> pairs, for example.
>
> but there are no 'pairs' in the list except by the context of
> assigning the list to a hash.


I'm sorry, but I really have to disagree here. A hash is essentially a
list divided into pairs (keys and values, respectively), and `map { $_
=> s> 1 }` is creating such a pair in a statement like that.

--
szr


A. Sinan Unur

2008-03-29, 7:19 pm

"szr" <szrRE@szromanMO.comVE> wrote in
news:fslqmd01gvu@news2.newsguy.com:

> Uri Guttman wrote:
>
> I understand, but still, whatever is being generated to the LHS of
> map, it's done that many times are there are elements in the list
> on the RHS. Is that fair to say?


If I understand you correctly, yeah, that's fine to say.

On the other hand, you might find the following example instructive:

#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

my @result = map { split // } ( '5' x rand(10) ) ;

print Dumper \@result;

__END__

Note that, the RHS is always a single element list. On the other hand,
the number of elements in the result of map is variable. So, yes, the
operation inside the block is only carried out once, what you are
saying is fair in that sense, but the map operation can change the
length of the list in non-simplistic ways:

E:\Home\asu1\Src\Test> t1.pl
$VAR1 = [];

E:\Home\asu1\Src\Test> t1.pl
$VAR1 = [
'5',
'5',
'5',
'5',
'5',
'5',
'5'
];

E:\Home\asu1\Src\Test> t1.pl
$VAR1 = [
'5',
'5',
'5',
'5'
];

Sinan


--
A. Sinan Unur <1usa@llenroc.ude.invalid>
(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW:
http://www.rehabitation.com/clpmisc/
Uri Guttman

2008-03-29, 7:19 pm

>>>>> "s" == szr <szrRE@szromanMO.comVE> writes:

s> Well that's basically how I understand it. In fact it seems you
s> basically restated the same thing in a different way. 1) the expr/block
s> is executed once per cycle. Yep. 2) The end result is something that is
s> a grouping, whether singular (say, a simple list) or more complex (like,
s> say, a hash key/value pair), of the same amount of elements in the input
s> list.


you keep saying grouping and that is the wrong way to think about
it. drop that word from this concept. map generates ONE list. how it
gets there is irrelevent so there is no grouping.
[color=darkred]

s> I'm sorry, but I really have to disagree here. A hash is essentially a
s> list divided into pairs (keys and values, respectively), and `map { $_
s> => s> 1 }` is creating such a pair in a statement like that.
no. a hash creates the pairs when it is assigned a list. the map just
generates a list with no real 'pairs'. you may think they are there but
they are not pairs yet. you have to separate what the map does from what
the hash expects.

uri

--
Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Free Perl Training --- http://perlhunter.com/college.html ---------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
szr

2008-03-29, 7:19 pm

A. Sinan Unur wrote:
> "szr" <szrRE@szromanMO.comVE> wrote in
> news:fslqmd01gvu@news2.newsguy.com:
>
>
> If I understand you correctly, yeah, that's fine to say.
>
> On the other hand, you might find the following example instructive:
>
> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> use Data::Dumper;
>
> my @result = map { split // } ( '5' x rand(10) ) ;
>
> print Dumper \@result;
>
> __END__
>
> Note that, the RHS is always a single element list. On the other hand,
> the number of elements in the result of map is variable. So, yes, the
> operation inside the block is only carried out once, what you are
> saying is fair in that sense, but the map operation can change the
> length of the list in non-simplistic ways:


Nice example. And yes, this does go with my point. Perhaps I should of
said, the number of elements on the RHS dictates how many passes map
will make. In this case, it's indeed once, where split creates the list
(in fact the map statement is obviously redundant, but I see your
point.)

Thanks.

--
szr


Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com