Click here to get back home

Readline using foreach and while

 HomeNewsGroups | Search | About
 comp.lang.perl.misc    Post an article   get this group's latest topics as an RSS feed add this group's latest topics to your My MSN content add this group's latest topics to your My Yahoo content
Subject Author Date
Readline using foreach and while Saurabh Jain 03-25-2008
Posted by szr on March 29, 2008, 4:39 pm
Please log in for more thread options
A. Sinan Unur wrote:
>
>> Uri Guttman wrote:
>>>
>>> >> Absolutely not. my %h = map { $_ => 1 } qw/a b c/; is quite a
>>> 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?
>
> 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



Posted by nolo contendere on March 28, 2008, 10:13 am
Please log in for more thread options
> Peter J. Holzer wrote:
> >> nolo contendere wrote:
> >>> 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 ) {
> >>> =A0 =A0 push @ary, 'd' if /c/;
> >>> =A0 =A0 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."
>
> > Yes. But the same should be true for
>
> > for (@ary) {
> > =A0 =A0...
> > }
>
> > 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.
>

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?

Posted by xhoster on March 26, 2008, 11:35 am
Please log in for more thread options

> >
> > 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>) { ... } ),

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.

Posted by Ben Morrow on March 26, 2008, 10:08 am
Please log in for more thread options

> Ben Morrow wrote:
> >>
> >> 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...
>
> 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


Posted by nolo contendere on March 25, 2008, 1:50 pm
Please log in for more thread options
> Ben Morrow wrote:
> >>On Tue, 25 Mar 2008 11:59:23 +0000, John W. Krahn wrote:
> >>>Ben Bullock 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"
>
> Hm. Why is this distinction relevant here?
>
> > 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 =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.lang.perl.misc/msg/9f2ebca559578bcf

Similar ThreadsPosted
Asynchronous readline? September 6, 2004, 9:27 am
Term::ReadLine::GNU problem January 1, 2006, 11:57 am
ReadKey/ ReadLine query July 4, 2006, 2:40 am
readline - possible security hole March 30, 2007, 8:50 am
circular references, chdir() and Term::ReadLine::Gnu? February 7, 2006, 8:09 pm
Strange characters using Term::Readline on Win32 July 28, 2006, 9:05 am
HELP: readline() on unopened filehandle DATA at G:/PERLLIB/LIB/site_perl/5.8.2/MIME/WordDecoder.pm line 579. May 21, 2006, 10:59 am
foreach vs. for October 24, 2004, 6:18 pm
foreach in my May 18, 2005, 10:40 am
Using foreach?? maybe.. June 3, 2007, 12:30 pm

Our other projects:

Art Dolls, Fairies and Mermaids - Sunnyfaces.net

Roy's Linux, Programming and Search Engines messages

1-Script XML SitemapXML Sitemap