Re: Iffor

2006-04-20 Thread $Bill Luebkert
Glenn Linderman wrote:

 On approximately 4/19/2006 5:42 PM, came the following characters from 
 the keyboard of Sisyphus:
 
- Original Message - 
From: Glenn Linderman
.
.

I think that the

for( grep ($_ != 3, @a))

is quite clear in bundling the element selection together, and
separating it from the functions being performed.


I would much rather see (as suggested earlier on in this thread):

for(@a) {
 next if $_ == 3;

For me it is both clearer and more efficient ... but each to his own.

On the subject of replacing brackets with modifiers (which I think was also
raised earlier on), I was surprised to find that using a modifier is about
25% faster than brackets:


### try.pl ###
use warnings;
no warnings once;
use Benchmark;

@x = (1 .. 100);
@y = (1 .. 100);

$z1 = 0;
$z2 = 0;

timethese(1, {
'modifier' = 'for(@x) {$z1++ if $_ != 3}',
'brackets' = 'for(@y) {if($_ != 3){$z2++}}',
});

print \n, $z1,  , $z2, \n;
__END__

D:\pscrptperl try.pl
Benchmark: timing 1 iterations of brackets, modifier...
  brackets:  1 wallclock secs ( 1.03 usr +  0.00 sys =  1.03 CPU) @  0.97/s
(n=1)
(warning: too few iterations for a reliable count)
  modifier:  1 wallclock secs ( 0.70 usr +  0.00 sys =  0.70 CPU) @  1.43/s
(n=1)
(warning: too few iterations for a reliable count)

99 99

Maybe I've misinterpreted the results ??

Cheers,
Rob
 
 
 I get similar, but I guess my new computer is faster than yours, so I 
 did 10 iterations... and got 3.77 for brackets, and 2.44 for modifier. 
 Both your number and mine are closer to 30% than 25% faster.  Interesting.
 
 Get a load of this variation:
 
 perl
 use warnings;
 no warnings once;
 use Benchmark;
 
 @x = (1 .. 100);
 @y = (1 .. 100);
 @z = (1 .. 100);
 @w = (1 .. 100);
 
 $z1 = 0;
 $z2 = 0;
 $z3 = 0;
 $z4 = 0;
 
 timethese(10, {
 'forgrep' = 'for(grep($_ != 3, @w)){ $z4++ }',
 'next' = 'for(@z) {next if $_ == 3; $z3++}',
 'brackets' = 'for(@y) {if($_ != 3){$z2++}}',
 'modifier' = 'for(@x) {$z1++ if $_ != 3}',
 });
 
 print \n, $z1,  , $z2,  , $z3,  , $z4, \n;
 __END__
 
 Benchmark: timing 10 iterations of brackets, forgrep, modifier, next...
brackets:  4 wallclock secs ( 3.73 usr +  0.00 sys =  3.73 CPU) @ 
 2.68/s (n=10)
 forgrep:  3 wallclock secs ( 3.19 usr +  0.00 sys =  3.19 CPU) @ 
 3.14/s (n=10)
modifier:  3 wallclock secs ( 2.61 usr +  0.00 sys =  2.61 CPU) @ 
 3.83/s (n=10)
next:  3 wallclock secs ( 2.64 usr +  0.00 sys =  2.64 CPU) @ 
 3.79/s (n=10)

Don't know how you could get that to run on only 10 iterations.

I ran 10 million iterations and got:

timethese (slight format mod to fit line):
Benchmark: timing 1000 iterations of brackets, forgrep, modifier, next...
 brackets:  9 secs ( 4.91 usr + 0.00 sys = 4.91 CPU) @ 2037905.03/s (n=1000)
  forgrep: 24 secs (12.20 usr + 0.00 sys = 12.20 CPU) @ 819470.62/s (n=1000)
 modifier: 10 secs ( 4.80 usr + 0.02 sys = 4.81 CPU) @ 2077706.21/s (n=1000)
 next: 10 secs ( 4.81 usr + 0.00 sys = 4.81 CPU) @ 2078137.99/s (n=1000)

cmpthese 1000:
  Rate  forgrep next modifier brackets
forgrep   810110/s   -- -60% -61% -62%
next 2045408/s 152%   --  -1%  -4%
modifier 2071251/s 156%   1%   --  -3%
brackets 2133561/s 163%   4%   3%   --


 990 990 990 990
 
 
 
 I have to admit that if the complexity of the filter expression was more 
 than one comparison or match, that I'd rather see them in the body of 
 the loop, too.  But for one comparison, I kind of like the for-grep.
 


-- 
  ,-/-  __  _  _ $Bill LuebkertMailto:[EMAIL PROTECTED]
 (_/   /  )// //   DBE CollectiblesMailto:[EMAIL PROTECTED]
  / ) /--  o // //  Castle of Medieval Myth  Magic http://www.todbe.com/
-/-' /___/__/_/_http://dbecoll.tripod.com/ (My Perl/Lakers stuff)
___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


Re: Iffor

2006-04-20 Thread John Deighan

At 12:44 AM 4/20/2006, Chris Wagner wrote:

At 10:42 AM 4/20/2006 +1000, Sisyphus wrote:
On the subject of replacing brackets with modifiers (which I think was also
raised earlier on), I was surprised to find that using a modifier is about
25% faster than brackets:
'modifier' = 'for(@x) {$z1++ if $_ != 3}',
'brackets' = 'for(@y) {if($_ != 3){$z2++}}',

That is actually pretty well known.  The reason is that the former is a
short circuit style operation.  The code has a simple bifurcation.  In the
latter it is a code block which has to be setup for all the potential things
u can put in a code block.  Like my's, labels, etc.  Simply entering a curly
bracket costs money.  That's why it's best to avoid them unless ur stringing
just way too many and's and or's together.


And is there some reason that the compiler couldn't optimize that 
away by checking

to see if there are any my's, labels, etc. and avoiding the setup in that case?

___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


Re: Iffor

2006-04-20 Thread $Bill Luebkert
Glenn Linderman wrote:

 The whole session is there in my message... I don't know how either, it 
 was my first use of Benchmark, I cloned it from Rob  changed his 1 
 (which produced a warning) to 10 (which didn't).  And added a couple new 
 cases.
 
 Clearly you got different results from more iterations; generally with 
 benchmarks and low-res timers, more iterations produce more reliable 
 results (known from previous life doing benchmarks; I know nothing about 
 Perl's Benchmark, except I see results posted from time to time).
 
 How do you get the cmpthese results?  I've only seen these posted a 
 few times, recently.

Just add cmpthese to the import list and change timethese to cmpthese.
___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


RE: Iffor

2006-04-19 Thread Ng, Bill



Thanks,

 Just ordered it from Amazon. 
Went the super-cheap route and ordered it free shipping ... should have it in a 
week or so.

 If anyone cares, I ended up using 
this asmy 
code ... it accomplished exactly what I was looking 
for:
---
for (grep($_ !~ /$zipDir/i, 
@folders))
---

 
For those who weren't fond of that .. I'm sorry, but I did comment the hell out 
of that line =)

Bill 
Ng



From: D D Allen [mailto:[EMAIL PROTECTED] 
Sent: Tuesday, April 18, 2006 8:55 PMTo: Ng, 
BillCc: perl-win32-users@listserv.ActiveState.comSubject: 
Re: Iffor

snip good advice
Read Damian Conway's Perl Best Practices. 
And when you feel the need to write clever code, read it 
again./snip
___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


RE: Iffor

2006-04-19 Thread Arms, Mike
Bill Ng [bill.ng AT citigroup.com] wrote:
 Thanks,

 Just ordered it from Amazon.  Went the super-cheap route and ordered
 it free shipping ... should have it in a week or so.

  If anyone cares, I ended up using this as my code ... it accomplished
 exactly what I was looking for:
 ---
 for (grep($_ !~ /$zipDir/i, @folders))
 ---

 For those who weren't fond of that .. I'm sorry, but I did comment
 the hell out of that line =)

 Bill Ng


 D D Allen [dewey.allen AT us.ibm.com]
 snip good advice
   Read Damian Conway's Perl Best Practices.  And when you feel
   the need to write clever code, read it again.
 /snip
 
Bill, as long as your goal was *less efficient and obfuscated code*,
then you succeeded. You do realize that you are making a second
copy of all of the contents of @folders less the items that do
not match your regex? In the general case, if @folders is very
large, this is hugely expensive in terms of memory compared to
iterating across the list and just not doing whatever action if
the regex does not match. In both cases you are doing the test
against each element. As far as obfuscation, yes I read that you
commented the hell out of it, but that is little comfort for
doing something so obscure and needless. Not only is it harder
to maintain, I would suggest that it is harder to extend. And
my pity if this code is handed to someone else to maintain.
 
In a subsequent post, D D Allen wrote:
 Save cleverness for the times when it could make a significant,
 measurable difference.
 
Sing it, brother!
 
--
Mike Arms


___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


RE: Iffor

2006-04-19 Thread Ng, Bill
@folders will have, at most 7 objects in it.  All strings of less than
80 bytes.

Bill Ng 

-Original Message-
From: Arms, Mike [mailto:[EMAIL PROTECTED] 
Sent: Wednesday, April 19, 2006 5:24 PM
To: perl-win32-users@listserv.ActiveState.com
Cc: Ng, Bill
Subject: RE: Iffor

Bill, as long as your goal was *less efficient and obfuscated code*,
then you succeeded. You do realize that you are making a second copy of
all of the contents of @folders less the items that do not match your
regex? In the general case, if @folders is very large, this is hugely
expensive in terms of memory compared to iterating across the list and
just not doing whatever action if the regex does not match. In both
cases you are doing the test against each element. As far as
obfuscation, yes I read that you commented the hell out of it, but that
is little comfort for doing something so obscure and needless. Not only
is it harder to maintain, I would suggest that it is harder to extend.
And my pity if this code is handed to someone else to maintain.
 
--
Mike Arms


___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


Re: Iffor

2006-04-19 Thread Sisyphus

- Original Message - 
From: Glenn Linderman
.
.

 I think that the

 for( grep ($_ != 3, @a))

 is quite clear in bundling the element selection together, and
 separating it from the functions being performed.


I would much rather see (as suggested earlier on in this thread):

for(@a) {
 next if $_ == 3;

For me it is both clearer and more efficient ... but each to his own.

On the subject of replacing brackets with modifiers (which I think was also
raised earlier on), I was surprised to find that using a modifier is about
25% faster than brackets:


### try.pl ###
use warnings;
no warnings once;
use Benchmark;

@x = (1 .. 100);
@y = (1 .. 100);

$z1 = 0;
$z2 = 0;

timethese(1, {
'modifier' = 'for(@x) {$z1++ if $_ != 3}',
'brackets' = 'for(@y) {if($_ != 3){$z2++}}',
});

print \n, $z1,  , $z2, \n;
__END__

D:\pscrptperl try.pl
Benchmark: timing 1 iterations of brackets, modifier...
  brackets:  1 wallclock secs ( 1.03 usr +  0.00 sys =  1.03 CPU) @  0.97/s
(n=1)
(warning: too few iterations for a reliable count)
  modifier:  1 wallclock secs ( 0.70 usr +  0.00 sys =  0.70 CPU) @  1.43/s
(n=1)
(warning: too few iterations for a reliable count)

99 99

Maybe I've misinterpreted the results ??

Cheers,
Rob

___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


Re: Iffor

2006-04-19 Thread Sisyphus

- Original Message - 
From: Glenn Linderman
.
.

 Get a load of this variation:

 perl
 use warnings;
 no warnings once;
 use Benchmark;

 @x = (1 .. 100);
 @y = (1 .. 100);
 @z = (1 .. 100);
 @w = (1 .. 100);

 $z1 = 0;
 $z2 = 0;
 $z3 = 0;
 $z4 = 0;

 timethese(10, {
 'forgrep' = 'for(grep($_ != 3, @w)){ $z4++ }',
 'next' = 'for(@z) {next if $_ == 3; $z3++}',
 'brackets' = 'for(@y) {if($_ != 3){$z2++}}',
 'modifier' = 'for(@x) {$z1++ if $_ != 3}',
 });

 print \n, $z1,  , $z2,  , $z3,  , $z4, \n;
 __END__

 Benchmark: timing 10 iterations of brackets, forgrep, modifier, next...
brackets:  4 wallclock secs ( 3.73 usr +  0.00 sys =  3.73 CPU) @
 2.68/s (n=10)
 forgrep:  3 wallclock secs ( 3.19 usr +  0.00 sys =  3.19 CPU) @
 3.14/s (n=10)
modifier:  3 wallclock secs ( 2.61 usr +  0.00 sys =  2.61 CPU) @
 3.83/s (n=10)
next:  3 wallclock secs ( 2.64 usr +  0.00 sys =  2.64 CPU) @
 3.79/s (n=10)

 990 990 990 990


Yeah  beats me how 'forgrep' could be faster than 'brackets'.

I had also done some timings on use of 'next' and found it to be
inexplicably fast. IIRC, there is very little difference (timewise) between
next if $_ == 3; and if($_ == 3) {next}. At one stage I got the
impression that $_==3 could be evaluated more quickly than $_!=3, but I
don't know if that's so.

Anyway . I probably wouldn't understand it even if it was explained to
me :-)

Cheers,
Rob

___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


Re: Iffor

2006-04-19 Thread Chris Wagner
At 10:42 AM 4/20/2006 +1000, Sisyphus wrote:
On the subject of replacing brackets with modifiers (which I think was also
raised earlier on), I was surprised to find that using a modifier is about
25% faster than brackets:
'modifier' = 'for(@x) {$z1++ if $_ != 3}',
'brackets' = 'for(@y) {if($_ != 3){$z2++}}',

That is actually pretty well known.  The reason is that the former is a
short circuit style operation.  The code has a simple bifurcation.  In the
latter it is a code block which has to be setup for all the potential things
u can put in a code block.  Like my's, labels, etc.  Simply entering a curly
bracket costs money.  That's why it's best to avoid them unless ur stringing
just way too many and's and or's together.





--
REMEMBER THE WORLD TRADE CENTER ---= WTC 911 =--
...ne cede malis

0100

___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


RE: Iffor

2006-04-18 Thread Arms, Mike
Bill Ng [bill.ng AT citigroup.com] wrote:
 Syntax issue (I think),
 
 I'm trying to do the following:
 I need to execute a block of instructions for all items in an array
 except for one.
 
 So if my array was:
 @a=(1,2,3,4,5);
 And we assume that I don't want to execute the block if the value of
$_
 is 3 ...
 
 Then, in my head, I'm looking for the WORKING (key word there) version
 of this:
 ---
 @a = (1,2,3,4,5);
 if ($_ != 3) for (@a)
 {
   print something;
   doSomething();
   print somethingelse;
   yada($yada{$ya})
 }
 -
 
 But that if ... for line doesn't work.
 Neither does:
 
 for (@a, $_ != 3) {}
 
 
 Anyone got any ideas?  I've always done this by running a standard for
 loop and having an if condition inside the loop .. but that seems
 inefficient to me right now and I'm looking for the easier way.

Don't think you'll find anything simpler than the old standard next if
expr :

for ( @a ) {
next if $_ == 3;
print something;
doSomething();
print somethingelse;
yada($yada{$ya})
}

--
Mike Arms


___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


RE: Iffor

2006-04-18 Thread Timothy Johnson

How about this?

###

use strict;
use warnings;

my @a = (1,2,3,4,5);
foreach(@a){
   unless($_ == 3){
  #do something...
   }
}

###




-Original Message-
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of
Ng, Bill
Sent: Tuesday, April 18, 2006 12:59 PM
To: perl-win32-users@listserv.ActiveState.com
Subject: Iffor

snip

So if my array was:
@a=(1,2,3,4,5);
And we assume that I don't want to execute the block if the value of $_
is 3 ...

Then, in my head, I'm looking for the WORKING (key word there) version
of this:
---
@a = (1,2,3,4,5);
if ($_ != 3) for (@a)
{
  print something;
  doSomething();
  print somethingelse;
  yada($yada{$ya})
}
-

snip


___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


RE: Iffor

2006-04-18 Thread Timothy Johnson

Okay, I'm a moron.  I somehow missed that last line.  Disregard...

IMHO you probably wouldn't gain any significant performance here even if
you succeeded in the syntax you are looking for because you still have
to do a check for each iteration of the loop.  

The only thing else I can think of is if you knew the element of the
list you wanted to skip ahead of time and then iterated through the
array slice of the elements you wanted to keep.  That might save a few
cycles if the elements you throw away are towards the beginning of your
array, but for the minimal amount you gain it's probably not worth it.

This might be a good one to run by the guys at the beginners@perl.org
mailing list.  There are some guys over there that are pretty sharp when
it comes to picking the right algorithm for a particular task.


-Original Message-
From: Timothy Johnson 
Sent: Tuesday, April 18, 2006 2:28 PM
To: 'Ng, Bill'; perl-win32-users@listserv.ActiveState.com
Subject: RE: Iffor


How about this?

###

use strict;
use warnings;

my @a = (1,2,3,4,5);
foreach(@a){
   unless($_ == 3){
  #do something...
   }
}

###




-Original Message-
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of
Ng, Bill
Sent: Tuesday, April 18, 2006 12:59 PM
To: perl-win32-users@listserv.ActiveState.com
Subject: Iffor

snip

So if my array was:
@a=(1,2,3,4,5);
And we assume that I don't want to execute the block if the value of $_
is 3 ...

Then, in my head, I'm looking for the WORKING (key word there) version
of this:
---
@a = (1,2,3,4,5);
if ($_ != 3) for (@a)
{
  print something;
  doSomething();
  print somethingelse;
  yada($yada{$ya})
}
-

snip


___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


RE: Iffor

2006-04-18 Thread Ng, Bill
Thanks anyway Tim,

Performance isn't really what I'm going for, just simpler code.
For the past 4 years, I've been coding to get the job done, no matter
how many lines it takes or how ugly it is to read, as long as it works
that's fine.  But recently you guys have shown me how to simplify my
code and make things infinitely easier to read.  So for the past day or
so I've been writing a script that does some log file zipping/deleting
based on last-modified time and I'm trying to do it as neatly as
possible.  Entire script runs in less than 30 seconds so performance
isn't much of an issue, just looking to tidy up the code.  Thanks again.

Bill 

-Original Message-
From: Timothy Johnson [mailto:[EMAIL PROTECTED] 
Sent: Tuesday, April 18, 2006 5:41 PM
To: Ng, Bill; perl-win32-users@listserv.ActiveState.com
Subject: RE: Iffor


Okay, I'm a moron.  I somehow missed that last line.  Disregard...

IMHO you probably wouldn't gain any significant performance here even if
you succeeded in the syntax you are looking for because you still have
to do a check for each iteration of the loop.  

The only thing else I can think of is if you knew the element of the
list you wanted to skip ahead of time and then iterated through the
array slice of the elements you wanted to keep.  That might save a few
cycles if the elements you throw away are towards the beginning of your
array, but for the minimal amount you gain it's probably not worth it.

This might be a good one to run by the guys at the beginners@perl.org
mailing list.  There are some guys over there that are pretty sharp when
it comes to picking the right algorithm for a particular task.


___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


RE: Iffor

2006-04-18 Thread Jerry Kassebaum

@a = (1,2,3,4,5);

for $x (@a)

{
if($x==3){next;}
print $x\n;

}

##

You wrote:

Syntax issue (I think),

I'm trying to do the following:
I need to execute a block of instructions for all items in an array
except for one.

So if my array was:
@a=(1,2,3,4,5);
And we assume that I don't want to execute the block if the value of $_
is 3 ...

Then, in my head, I'm looking for the WORKING (key word there) version
of this:
---
@a = (1,2,3,4,5);
if ($_ != 3) for (@a)
{
 print something;
 doSomething();
 print somethingelse;
 yada($yada{$ya})
}
-

But that if ... for line doesn't work.
Neither does:

for (@a, $_ != 3) {}


Anyone got any ideas?  I've always done this by running a standard for
loop and having an if condition inside the loop .. but that seems
inefficient to me right now and I'm looking for the easier way.

Bill Ng


___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


RE: Iffor

2006-04-18 Thread Suresh Govindachar
  
  Ng, Bill asked on April 18, 2006 12:59 PM

   So if my array was:
   @a=(1,2,3,4,5);
   And we assume that I don't want to execute the block if the
   value of $_ is 3 ...
   
   Then, in my head, I'm looking for the WORKING (key word there)
   version of this:
   ---
   @a = (1,2,3,4,5);
   if ($_ != 3) for (@a)
   {
 print something;
 doSomething();
 print somethingelse;
 yada($yada{$ya})
   }
   -

  use strict;
  use warnings;
  
my @a=(1..5);

# don't like this 
#
print grep {$_ != 3} (1 .. 5); 
   
# don't like this either 
#
for (grep {$_ != 3} @a)
{
   print $_  ;
}

# OK
#
for (@a)
{
   ($_ == 3) and next; # or: next if $_ == 3;
   print $_  ;
}

  #--Suresh
  
__END__


 

___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


RE: Iffor

2006-04-18 Thread Ng, Bill
Read the last sentence of my email ... =)

Bill Ng 

-Original Message-
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of
Jerry Kassebaum
Sent: Tuesday, April 18, 2006 6:07 PM
To: perl-win32-users@listserv.ActiveState.com
Subject: RE: Iffor

@a = (1,2,3,4,5);

for $x (@a)

{
if($x==3){next;}
print $x\n;

}

##

You wrote:

Syntax issue (I think),

I'm trying to do the following:
I need to execute a block of instructions for all items in an array
except for one.

So if my array was:
@a=(1,2,3,4,5);
And we assume that I don't want to execute the block if the value of $_
is 3 ...

Then, in my head, I'm looking for the WORKING (key word there) version
of this:
---
@a = (1,2,3,4,5);
if ($_ != 3) for (@a)
{
  print something;
  doSomething();
  print somethingelse;
  yada($yada{$ya})
}
-

But that if ... for line doesn't work.
Neither does:

for (@a, $_ != 3) {}


Anyone got any ideas?  I've always done this by running a standard for
loop and having an if condition inside the loop .. but that seems
inefficient to me right now and I'm looking for the easier way.

Bill Ng


___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


RE: Iffor

2006-04-18 Thread Suresh Govindachar

   Ng, Bill wrote: 

 Performance isn't really what I'm going for, just simpler code.
  
   For the past 4 years, I've been coding to get the job done, no
   matter how many lines it takes or how ugly it is to read, as
   long as it works that's fine.  But recently you guys have shown
   me how to simplify my code and make things infinitely easier to
   read.  So for the past day or so I've been writing a script that
   does some log file zipping/deleting based on last-modified time
   and I'm trying to do it as neatly as possible.  Entire script
   runs in less than 30 seconds so performance isn't much of an
   issue, just looking to tidy up the code.  Thanks again.

  Given your present mind-set, I suspect you'll benefit from
  critically thinking about the issues Damian Conway raises and
  addresses in his Perl Best Practices -- consider not just the
  issues he raises and his resolution of them -- consider also
  whether the issues he raises are valid and whether he has missed
  any issues.

  --Suresh

___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


Re: Iffor

2006-04-18 Thread Lyle Kopnicky

Ng, Bill wrote:

Performance isn't really what I'm going for, just simpler code.
If clear code is what you want, you won't get it using a 'next' as some 
have suggested.  A 'next' syntactically looks like any other line, and 
is therefore not easily noticed as part of the control flow.  Unless, 
perhaps, you put a big comment next to it.  Like a 'return' or a 'die', 
it's easily glanced over, and should only be used for exceptional 
circumstances.


I recommend you either:

  1. Embed the 'if' inside the 'for' - this makes it clear what you are
 trying to do.  It is not a significant performance penalty.
  2. Filter out just the items you want to iterate over in advance,
 using 'grep'.

First method:

@a = (1,2,3,4,5);
for (@a) {
   if ($_ != 3) {
   print something;
   doSomething();
   print somethingelse;
   yada($yada{$ya});
   }
}

Second method:

@a = (1,2,3,4,5);
for (grep { $_ != 3 } @a) {
   print something;
   doSomething();
   print somethingelse;
   yada($yada{$ya});
}

Personally, I think the second method is the clearest.  You are 
explicitly stating what you are iterating over.  You might even write:


@a = (1,2,3,4,5);
@a_subset = grep { $_ != 3 }; # comment about why I only want these
for (@a_subset) {
   ...
}

Naming intermediate steps is good documentation.

The only reason I'd use the first method is if the condition for the 
'if' could change during the iteration of the loop.  But I try to avoid 
those sorts of situations.


--
Lyle Kopnicky
Software Project Engineer
Veicon Technology, Inc.

___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


Re: Iffor

2006-04-18 Thread D D Allen

[Soap box warning...]

You seem to be suffering from a common
perl programming psychosis: the sometimes unbearable urge to write clever
perl in the fewest possible number of lines ... that infects us all from
time to time...

Read Damian Conway's Perl Best Practices.
And when you feel the need to write clever code, read it again.

Take a step back and think about the
difference between the following... (besides the fact that the first way
doesn't work)

if ($_ != 3) for (@a) {
} 


for (@a) { 
if
($_ != 3) {
}
}

Two brackets?  The for-if version
is readily understandable to anyone who reads your code (including yourself
6 - 9 - 12 months later). Your if-for version, even if it did work,
will confuse many, most, all, maybe even yourself 6 months later.

Perl Best Practices: Chapter 1:
Page 4: ... optimize your programming style for readibility;
not writability. Better yet, try to optimize for comprehensibility;
easy-to-read and easy-to-understand are not necessarily the same thing.

And Perl Best Practices would suggest
that the following is stylistically best from a readibility / comprehensibility
perspective as it avoids the use of the magic variable $_

foreach my $a (@a) {
if
($a != 3) {

   print $a\tsomething\n;
}
}

Save cleverness for the times when it
could make a signficant, measurable difference. Saving two brackets
is useless cleverness.

Concerning your if-for code that doesn't
work, see perlsyn in the ActivePerl user guide.

Any
simple statement may optionally be followed by a SINGLE modifier, just
before the terminating semicolon (or block ending). The possible modifiers
are:

  if EXPR
  unless EXPR
  while EXPR
  until EXPR
  foreach LIST

So this is legal syntax:

print $_\tsomething\n foreach
(@a);

But this is not because the if block
is not a simple statement.

if ($_ != 3) {
print
$_\tsomething\n;
} foreach (@a);


Maybe the closest to your envisioned
clever solution is the apply function available in the List::MoreUtils
perl module. See the last example in the following that uses apply.

use strict;
use warnings;

my @a = (1,2,3,4,5);

print $_\tsomething 1\n
foreach (@a);

# this isn't legal perl syntax...
#
#if ($_ != 3) {   
  
#print
$_\tsomething 1\n;
#} foreach (@a);   


print \nstandard foreach loop
with interior if\n;
foreach my $a (@a) {
if
($a != 3) {

   print $a\tsomething 2\n;
}
}


print \nstandard foreach loop
with next\n;
foreach my $a (@a) {
next
if ($a == 3);
print
$a\tsomething 3\n;
}

print \nList::MoreUtils apply
method\n;

use List::MoreUtils qw(apply);

apply { print $_\tsomething 4\n
if ($_ != 3)} @a;




Regards,

... Dewey







Ng, Bill [EMAIL PROTECTED]

Sent by: [EMAIL PROTECTED]
04/18/2006 03:59 PM




To
perl-win32-users@listserv.ActiveState.com


cc



Subject
Iffor








Syntax issue (I think),

I'm trying to do the following:
I need to execute a block of instructions for all items in an array
except for one.

So if my array was:
@a=(1,2,3,4,5);
And we assume that I don't want to execute the block if the value of $_
is 3 ...

Then, in my head, I'm looking for the WORKING (key word there) version
of this:
---
@a = (1,2,3,4,5);
if ($_ != 3) for (@a)
{
 print something;
 doSomething();
 print somethingelse;
 yada($yada{$ya})
}
-

But that if ... for line doesn't work.
Neither does:

for (@a, $_ != 3) {}


Anyone got any ideas? I've always done this by running a standard
for
loop and having an if condition inside the loop .. but that seems
inefficient to me right now and I'm looking for the easier way.

Bill Ng

___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs