Foreach

U

Uri Guttman

MG> Of course, there is a "map" equivalent, too:

MG> map { print "$_\n"; } @ARGV;

MG> I find that to be the most elegant way of looping through arrays. Of
MG> course, if you need the global $_ variable, for instance for reading a
MG> file, this trick is not applicable.

and that is considered to be very poor perl code. it is using map in a
void context. in older perls it would actually build up a list and throw
it away wasting ram and cpu. newer perls don't do that but it it still
poor style. map is for making a NEW LIST from an existing list. so it
should have output that is used. ignoring the output will confuse the
reader. and perl HAS a similar thing that is what you want: the foreach
modifier.

print "$_\n" foreach @ARGV ;

don't use map in a void context!

uri
 
U

Uri Guttman

DD> I know that. The problem is that you don't have it within the loop.

DD> My post was, basically, describing my taste. It doesn't make much sense
DD> to discuss somebody's taste. So, in closing, you can agree with me or you
DD> can have a bad taste.

you can not only disagree with coding style, some styles are objectively
(yes, not subjectively) better than others. you need to learn this.

DD> PS:
DD> Before you explode, the last sentence was a joke.

and my comment wasn't a joke. i have read too much poor perl to be funny
about this.

uri
 
W

Willem

Deadly Dirk wrote:
) On Tue, 09 Nov 2010 17:22:04 +0000, Willem wrote:
)> Wrong. The $_ is aliased to the elements and after the loop you get the
)> original value back.
)
) I know that. The problem is that you don't have it within the loop.

You were talking about using map for a loop. If you use map for long
loops where you need access to the global $_ then you really are a joke.

)> So, in closing, I totally disagree with your whole post.
)
) My post was, basically, describing my taste. It doesn't make much sense
) to discuss somebody's taste.

My post, on the other hand, was giving objective arguments as to why your
"taste" is bad, therefore it makes perfect sense. Your dismissal is
therefore off the mark and pointless.

) So, in closing, you can agree with me or you can have a bad taste.
)
) PS:
) Before you explode, the last sentence was a joke.

As was the rest of your post.

This sentence is no joke:
Your taste is not bad, your taste is objectively *wrong*.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
D

Dr.Ruud

That localizes $, but not $\, so the modified value of $\ is
retained after the block.

Ah, thanks for the review.

{local($\,$,)=($/)x2;print @ARGV}

also known as

print join( $/, @ARGV ), $/;

(though not fully equivalent)
 
U

Uri Guttman

R> {local($\,$,)=($/)x2;print @ARGV}

R> also known as

R> print join( $/, @ARGV ), $/;

might as well go back to print map "$_$/", @ARGV

uri
 
K

Keith Thompson

Dr.Ruud said:
Ah, thanks for the review.

{local($\,$,)=($/)x2;print @ARGV}

also known as

print join( $/, @ARGV ), $/;

(though not fully equivalent)

I'm mildly astonished that "x2" is tokenized as "x" followed by
"2" and not as a bareword.

Of course the space between "print" and "@ARGV" is unnecessary.

(Note to newbies: these are *not* examples of good style.)
 
J

J. Gleixner

Keith said:
I'm mildly astonished that "x2" is tokenized as "x" followed by
"2" and not as a bareword.

From perlop:

Binary "x" is the repetition operator. [...] In list context, if
the left operand is enclosed in parentheses or is a list formed
by qw/STRING/, it repeats the list.
 
M

Mladen Gogala

don't use map in a void context!

Uri, I read that several times. There was even a thread on Perlmonks
about it:


http://www.perlmonks.org/index.pl?node_id=296742


However, they say that this use is not deprecated, but "derided". Perl
5.8 and later doesn't necessarily build an output list, unless
specifically requested. I must confess to have written numerous code
snippets, especially with regular expressions:

map { s/.../.../; } @array;

simply because it's shorter than foreach my $x (@array) {
$x=~ s/.../.../;
}

I even benchmarked one version against the other, finding the speed to be
approximately the same. Is that disdain for the map in void context just
a custom or is based on some real problems caused by the code like that?
Thanks for your time and comments.
 
W

Willem

Mladen Gogala wrote:
) map { s/.../.../; } @array;
)
) simply because it's shorter than foreach my $x (@array) {
) $x=~ s/.../.../;
) }

But not shorter than:

s/.../.../ for @array;


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
K

Keith Thompson

J. Gleixner said:
Keith said:
I'm mildly astonished that "x2" is tokenized as "x" followed by
"2" and not as a bareword.

From perlop:

Binary "x" is the repetition operator. [...] In list context, if
the left operand is enclosed in parentheses or is a list formed
by qw/STRING/, it repeats the list.

Yes, I know what the "x" operator is. I'm just surprised that
(...)x2
tokenizes as
( ... ) x 2
rather than as
( ... ) x2
where "x2" would be a bareword (and a syntax error in this context).

I'm accustomed to, for example, C's "maximal munch" rule, where
as many characters as possible are gathered into a token, even
if it would create a syntax error when the resulting token stream
is parsed.

I'm not *entirely* surprised that Perl plays tricks in this
case to avoid a syntax error, but it doesn't do so in all cases.
For example, Perl scans "$x+++++$y" as "$x ++ ++ + $y", even though
it's a syntax error and "$x ++ + ++ $y" would be valid.

As the saying goes, only perl can parse Perl. I certainly wouldn't
count on "x2" being tokenized "correctly" if I wanted anyone to
be able to read the resulting code (obviously not a goal of what
we're doing here).
 
U

Uri Guttman

MG> Uri, I read that several times. There was even a thread on Perlmonks
MG> about it:


MG> http://www.perlmonks.org/index.pl?node_id=296742


MG> However, they say that this use is not deprecated, but "derided". Perl
MG> 5.8 and later doesn't necessarily build an output list, unless
MG> specifically requested. I must confess to have written numerous code
MG> snippets, especially with regular expressions:

MG> map { s/.../.../; } @array;

MG> simply because it's shorter than foreach my $x (@array) {
MG> $x=~ s/.../.../;
MG> }

and this is even shorter!

s/.../.../ for @array;

MG> I even benchmarked one version against the other, finding the speed to be
MG> approximately the same. Is that disdain for the map in void context just
MG> a custom or is based on some real problems caused by the code like that?
MG> Thanks for your time and comments.

you are missing the point. code is NOT for computers, it is for other
people to read. map is designed to make a list. if you use map in a void
context you are not making a list. regardless of whether perl makes a
list internally based on context, you are MISLEADING the reader of the
code. you are say i use map so look for a list but there IS NO LIST. the
for modifier (which you should learn) says i am doing something to each
element of the list so don't look for a return list. it tells the reader
more about your intention and doesn't mislead them. good code is making
it clear what you are doing for the reader of the code.

so to make it clear:

code is for people, NOT computers.

code is for OTHER people, not yourself.

burn those into your brain and you will instantly become a better coder.

uri
 
T

Ted Zlatanov

MG> Is that disdain for the map in void context just a custom or is
MG> based on some real problems caused by the code like that? Thanks
MG> for your time and comments.

I really don't think it's such a big deal. Yeah, it's not ideal, but
it's hardly a crime against humanity. I really, really doubt it will
cause maintenance problems long-term (as long as you're sure of having
Perl 5.8 or later). And it's quite readable.

OTOH I wouldn't use map in a void context in code I plan to put on CPAN
or publish openly. I don't want a thousand Uris telling me it's wrong;
arguing such things is a waste of time but the annoyance will linger.
I've had similar arguments about my preference for 1-space indents.

So judge the audience for your code and write it accordingly. When in
doubt, be conservative, explicit, and simple.

Ted
 
U

Uri Guttman

MG> Is that disdain for the map in void context just a custom or is
MG> based on some real problems caused by the code like that? Thanks
MG> for your time and comments.

TZ> I really don't think it's such a big deal. Yeah, it's not ideal, but
TZ> it's hardly a crime against humanity. I really, really doubt it will
TZ> cause maintenance problems long-term (as long as you're sure of having
TZ> Perl 5.8 or later). And it's quite readable.

readable or not, it is misleading to the reader. see my other post on that.

TZ> OTOH I wouldn't use map in a void context in code I plan to put on CPAN
TZ> or publish openly. I don't want a thousand Uris telling me it's wrong;
TZ> arguing such things is a waste of time but the annoyance will linger.
TZ> I've had similar arguments about my preference for 1-space indents.

indents can be changed with perltidy or editors. misleading code can't
be changed that way.

TZ> So judge the audience for your code and write it accordingly. When in
TZ> doubt, be conservative, explicit, and simple.

the audience judges your code, you don't judge the audience!

uri
 
K

Keith Thompson

Keith Thompson said:
Yes, I know what the "x" operator is. I'm just surprised that
(...)x2
tokenizes as
( ... ) x 2
rather than as
( ... ) x2
where "x2" would be a bareword (and a syntax error in this context).

I'm accustomed to, for example, C's "maximal munch" rule, where
as many characters as possible are gathered into a token, even
if it would create a syntax error when the resulting token stream
is parsed.

I'm not *entirely* surprised that Perl plays tricks in this
case to avoid a syntax error, but it doesn't do so in all cases.
For example, Perl scans "$x+++++$y" as "$x ++ ++ + $y", even though
it's a syntax error and "$x ++ + ++ $y" would be valid.

As the saying goes, only perl can parse Perl. I certainly wouldn't
count on "x2" being tokenized "correctly" if I wanted anyone to
be able to read the resulting code (obviously not a goal of what
we're doing here).

To make the point perhaps more clearly, I rather doubt that there's
anything in the Perl documentation from which one could reliably
conclude that "x2" in this context is treated an "x" operator
followed by a literal 2, rather than as a bareword (that would
result in a syntax error).
 
C

C.DeRykus

...
Yes, I know what the "x" operator is.  I'm just surprised that
    (...)x2
tokenizes as
    ( ... ) x 2
rather than as
    ( ... ) x2
where "x2" would be a bareword (and a syntax error in this context).

I'm not really surprised since the right paren
in ($/)x2 clearly would delimit a token break
(if that's the right characterization). Even
$/x2 without parens is ok which seems like
the parser helps out too:

perl -MO=Deparse -e "$/x2"
$/ x 2;
-e syntax OK


I'm accustomed to, for example, C's "maximal munch" rule, where
as many characters as possible are gathered into a token, even
if it would create a syntax error when the resulting token stream
is parsed.

Yes, that appears to happen in other cases. An
ordinary scalar for intance doesn't get special
handling like $/$x did:

perl -MO=Deparse -e "$xx2"
$xx2;
-e syntax OK
I'm not *entirely* surprised that Perl plays tricks in this
case to avoid a syntax error, but it doesn't do so in all cases.
For example, Perl scans "$x+++++$y" as "$x ++ ++ + $y", even though
it's a syntax error and "$x ++ + ++ $y" would be valid.

As the saying goes, only perl can parse Perl.  I certainly wouldn't
count on "x2" being tokenized "correctly" if I wanted anyone to
be able to read the resulting code (obviously not a goal of what
we're doing here).

Amen.
 
E

Eric Pozharski

with said:
OTOH I wouldn't use map in a void context in code I plan to put on CPAN
or publish openly. I don't want a thousand Uris telling me it's wrong;
arguing such things is a waste of time but the annoyance will linger.

I've just checked. B<map> in void context is use-warnings clean. But
one day it could change.

*CUT*
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,778
Messages
2,569,605
Members
45,238
Latest member
Top CryptoPodcasts

Latest Threads

Top