filter in perl

A

Andrea Spitaleri

Hi everyone,
I need to confirm a my doubt.
I use to make filter which they work perfectly. I am wondering if the
style of these scripts are perl-fashion or not. Ex in.txt:

home
dog
cat
home
car
bus
etc
etc

to grab the text from "home" to other "home" I use to do:

while(<>){
if(/^home/){
print;
while(<>){
print;
if(/^home/){
exit;
}}}}
to get:

home
dog
cat
home
but is not really perl style, i should say. any suggestion?

btw, in such way I print also the last line starting with home. If I
don't want print it?? so like:
home
dog
cat

many thanks

regards

andrea
 
J

Josef Moellers

Andrea said:
Hi everyone,
I need to confirm a my doubt.
I use to make filter which they work perfectly. I am wondering if the
style of these scripts are perl-fashion or not. Ex in.txt:

Why is everybody so hot to write "perl-ish" code?

Putting technical aspects (functionality, performance, stability) aside,
the best code is the code which you understand best.
Eg if you get confused by the implicit $_'s (like I do occasionally),
then don't use them, even if they are extreeeemy "perl-ish".
 
A

Anno Siegel

Andrea Spitaleri said:
Hi everyone,
I need to confirm a my doubt.
I use to make filter which they work perfectly. I am wondering if the
style of these scripts are perl-fashion or not. Ex in.txt:

home
dog
cat
home
car
bus
etc
etc

to grab the text from "home" to other "home" I use to do:

while(<>){
if(/^home/){
print;
while(<>){
print;
if(/^home/){
exit;
}}}}
to get:

home
dog
cat
home
but is not really perl style, i should say. any suggestion?

Most of all you're lacking indentation and white space.

while ( <> ) {
if ( /^home/ ) {
print;
while(<>){
print;
if(/^home/){
exit;
}
}
}
}

btw, in such way I print also the last line starting with home. If I
don't want print it?? so like:

home
dog
cat

Then swap the last "if" clause and the following "print" line.

Using "exit" to break out of a loop is overkill (you can take that
literally, it kills your program). Give the outer loop a label, say
"LOOP:", and replace "exit" with "last LOOP".

But you don't need deeply nested loops for this:

my $printing;
while ( <DATA> ) {
$printing = ! $printing if /^home/;
print;
}

does the same thing.

Anno
 
L

Lukas Mai

Andrea Spitaleri schrob:
Hi everyone,
I need to confirm a my doubt.
I use to make filter which they work perfectly. I am wondering if the
style of these scripts are perl-fashion or not. Ex in.txt:

to grab the text from "home" to other "home" I use to do:
[...]

while (<>) {
if (/home/ ... /home/) {
print;
}
}
btw, in such way I print also the last line starting with home. If I
don't want print it?? so like:
home
dog
cat

while (<>) {
if (my $seq = /home/ ... /home/) {
last if $seq =~ /E0$/;
print;
}
}

Read perldoc perlop about the "..." operator in scalar context.

HTH, Lukas
 
P

Paul Lalli

Hi everyone,
I need to confirm a my doubt.
I use to make filter which they work perfectly. I am wondering if the
style of these scripts are perl-fashion or not. Ex in.txt:

home
dog
cat
home
car
bus
etc
etc

to grab the text from "home" to other "home" I use to do:

while(<>){
if(/^home/){
print;
while(<>){
print;
if(/^home/){
exit;
}}}}
to get:

home
dog
cat
home
but is not really perl style, i should say. any suggestion?

This is almost exactly what the ... operator is intended for:

while (<DATA>){
print if /^home/ ... /^home/;
}
__DATA__
desk
home
dog
cat
home
car
bus


You can read about the ... operator in perldoc perlop
btw, in such way I print also the last line starting with home. If I
don't want print it?? so like:
home
dog
cat


For this one, I'd use the xor operator instead. Again, read about it in
perldoc perlop

my $flag;
while (<DATA>){
$flag = ($flag xor /^home/);
print if $flag;
}
__DATA__
desk
home
dog
cat
home
car
bus



Paul Lalli
 
A

Anno Siegel

Andrea Spitaleri said:
Hi everyone,
I need to confirm a my doubt.
I use to make filter which they work perfectly. I am wondering if the
style of these scripts are perl-fashion or not. Ex in.txt:

home
dog
cat
home
car
bus
etc
etc

to grab the text from "home" to other "home" I use to do:

while(<>){
if(/^home/){
print;
while(<>){
print;
if(/^home/){
exit;
}}}}
to get:

home
dog
cat
home
but is not really perl style, i should say. any suggestion?

Most of all you're lacking indentation and white space.

while ( <> ) {
if ( /^home/ ) {
print;
while(<>){
print;
if(/^home/){
exit;
}
}
}
}

btw, in such way I print also the last line starting with home. If I
don't want print it?? so like:

home
dog
cat

Then swap the last "if" clause and the following "print" line.

Using "exit" to break out of a loop is overkill (you can take that
literally, it kills your program). Give the outer loop a label, say
"LOOP:", and replace "exit" with "last LOOP".

But you don't need deeply nested loops for this:

my $printing;
while ( <DATA> ) {
$printing = ! $printing if /^home/;
print if $printing;
}

does the same thing.

Anno
 
M

Michele Dondi

Why is everybody so hot to write "perl-ish" code?

Putting technical aspects (functionality, performance, stability) aside,
the best code is the code which you understand best.
Eg if you get confused by the implicit $_'s (like I do occasionally),
then don't use them, even if they are extreeeemy "perl-ish".

Well, because as a matter of a fact "perl-ish" code is most likely to
be the kind of code a Perl programmer will understand best. Of course
this requires being somewhat acquainted with some particularities of
Perl's syntax and semantics regarding e.g. some functions like map()
or grep(), some operators like .. or short-circuiting of logical
operators, etc.

I remember a time when I could hardly understand what map() was about
and then I saw an example of Schwartzian transform and the only thing
I could think of it was that it seemed like a random sequence of
chars... but later on I even more or less rediscovered it by myself!
Now it's very natural to me...

I often happen to write scripts that take a bunch of directories as
arguments: these scripts often include lines like:


@ARGV=grep { -d or !warn "`$_': not a directory!\n" } @ARGV;
die <<"EOD" unless @ARGV;
Usage: $0 [options] <dir> [<dirs>]

-i <file> read cached info from <file>
-o <file> write cached info to <file>
EOD


these are very perl-ish IMHO and they are also very readable, still
IMHO, just because I'm used to Perl's syntax/semantics. For sure I
wouldn't have found them just as readable as a newbie. (I still
consider myself to be a newbie FWIW. But somewhat an advanced one!)

Please note that I'm not saying that good Perl programming should be
aimed at extremely concise code or golf(-like) tricks. For example in
the actual script from which I took the lines quoted above I also have
the following code a few lines below:


find { no_chdir => 1,
preprocess => sub {
sort {lc $a cmp lc $b} @_;
},
wanted => sub {
# ...
} }, @ARGV;


of course I may have written the whole thing like


find { no_chdir => 1,
# ...
} }, do {
my @t=grep { -d or !warn "`$_': not a directory!\n" }
@ARGV;
@t ? @t : die <<"EOD" };
...
...
EOD


But then this, however perl-ish may seem, would obscure the logical
flow of the script.


Michele
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top