The map function

J

Jim Cochrane

Thanks, Jim. Missing semicolons were the culprit:

#!/usr/bin/perl -w

use strict;
use warnings;

my $killrc = "sample.killrc";
my @filter;
my @list1 = qw( Mon Tu Wed);
open(FILE, "<$killrc") and do {
@filter = ();
foreach (<FILE>) {
chomp; length or next; /^#/o and next;
my $pat; eval '$pat = qr/$_/' or do {prompt $@; next};
push @filter, $pat;
};
close(FILE);

};
print @filter;
print @list1;

# perl mats5.pl 2>text50.txt >text51.txt
__END__
#end script begin output

(?-xism:^From:.*<[email protected]>)(?-xism:^Subject:.*MONEY)(?-xism:^Message-ID:.*googlegroups)MonTuWed

#end output show sample.killrc
^From:.*<[email protected]>
^Subject:.*MONEY
^Message-ID:.*googlegroups

Any ideas where the ?-xism is coming from?

I beg to differ. I snipped this from an actual, working perl program. How
do you know which braces need a semicolon after?

If I remember correctly, line 18 (from your error message) was either
the offending line with the close curly brace missing the ';' or the
line (print ...) below it. So you know where to look because of the
line # in the error message. Of course, now that you know that 'do {}'
blocks need a semicolon after them (right?), you know to look for that
now, too. (Of course, compile error messages will not always report a
line number that is at or very close to the actual problem in the code.)
sub read_killrc {
open(FILE, "<$killrc") and do {
@filter = ();
foreach (<FILE>) {
chomp; length or next; /^#/o and next;
my $pat; eval '$pat = qr/$_/' or do {prompt $@; next};
push @filter, $pat;
}
close(FILE);
};
}

The error had nothing to do with the print statements, but with a missing
token several lines before. At least now I've got output, so I can waddle
along.


--
 
U

Uri Guttman

JC> If I remember correctly, line 18 (from your error message) was either
JC> the offending line with the close curly brace missing the ';' or the
JC> line (print ...) below it. So you know where to look because of the
JC> line # in the error message. Of course, now that you know that 'do {}'
JC> blocks need a semicolon after them (right?), you know to look for that

actually do blocks are just expressions and the statement they might be
in will need a ; (and of course in perl ; is a statement separator and
not a terminator). in this case the do block was the end of the
statement and needed a ; before the print. an if block (or other flow
control block isn't a statement so they don't need ; after them.

uri
 
J

Jürgen Exner

Uri Guttman said:
JC> If I remember correctly, line 18 (from your error message) was either
JC> the offending line with the close curly brace missing the ';' or the
JC> line (print ...) below it. So you know where to look because of the
JC> line # in the error message. Of course, now that you know that 'do {}'
JC> blocks need a semicolon after them (right?), you know to look for that

actually do blocks are just expressions and the statement they might be
in will need a ; (and of course in perl ; is a statement separator and
not a terminator). in this case the do block was the end of the
statement and needed a ; before the print. an if block (or other flow
control block isn't a statement so they don't need ; after them.

Another reason to avoid do{} blocks that are dozens of lines long. At
the end of such a block you surely have forgotten, if it is a flow
controll block or an expression.

jue
 
G

Gunnar Hjalmarsson

Gerry said:
I could just omit it?

It's up to you; I for one do see a need for it: It prevents a fatal
error for the case a line is not a valid regular expression.

C:\home>type test.pl
my @filter;
while (<DATA>) {
chomp;
next unless length;
next if /^#/o;
my $pat;
eval '$pat = qr($_)' or do { warn $@; next };
push @filter, $pat;
}
print "$_\n" foreach @filter;

__DATA__
\w+).+?
\s+

C:\home>test.pl
Unmatched ) in regex; marked by <-- HERE in m/\w+) <-- HERE .+?/ at
(eval 1) line 1, <DATA> line 1.
(?-xism:\s+)

C:\home>
 
J

Jürgen Exner

Gerry Ford said:
My problem was that I thought I had a working script before I added the
print statements. At this point, I'm simply very error-prone.

Then it is even more important to follow standard procedures for your
own and others sake:

1: what is the expected behaviour?
2: what is the observed behaviour?
3: what code is producing this behaviour?
4: what data is producing this behaviour?
Those 4 elements are vital for any reasonable investigation.

You supplied 3, were vague about 1, and didn't tell anything about 2 or
4, so people had to use crystal balls and tea leaves to guess. And of
course they guessed wrong.
This is my
current version of this script, that I think addresses your criticisms:

[most of the code snipped]
You are still omitting a precise description of what you expect(1), what
you observe (2), and data to run your sample code (4).
my $pat; eval ('$pat = qr/$_/') or do {prompt $@; next};

You still got an 'interesting' do{} sitting around.
How would you indent this?

I would open the file in my favourite editor and run a "indent-region"
command.
I could just omit it?

Think! What is it that you are trying to achieve by using the eval()?
You didn't tell us. So how can we answer your question? If you don't
tell us then we cannot know what you are trying to do with that eval and
therefore cannot tell if the eval serves any purpose to achieve that
goal or not.

jue
 
J

Jürgen Exner

Gerry Ford said:
my $pat; eval ('$pat = qr/$_/') or do {prompt $@; next}; [...]

I'm still confused on the whole }; thing.

There is no }; thing. Understanding this is your problem.

There are 'blocks' that are enclosed in curly braces {.....}. Period.

And then there are statements. Individual statements are separated by a
; in Perl, i.e. between any two statements you have to write a ;.

In your original progam you had [reformatted to make it more obvious]
open(FILE, "<$killrc") and
do {SomeVeryLongWhatever} print @filter;

What you meant was
open(FILE, "<$killrc") and
do {SomeVeryLongWhatever};
print @filter;

If you want print() to be a new statement, then you have to place a
semicolon between the preceeding statement and the print(). If you don't
then you will get that syntax error because perl had to assume that you
are continuing the preceeding statement. After all, it could have been
that you wanted to add 5 to the result of do, something like

do {SomeVeryLongWhatever} + 5;

which is perfectly legal. The only way for perl to know that a new
statement is starting is if you put that semicolon there.
With this version, I've eliminated the the do{};

No, you haven't. See the one line of code I quoted above.
If I put a semicolon after the foreach close curly
brace, I get no change in behavior in the program. ??

That's just a surplus empty statement. Perl doesn't care if you create a
dozen or a million.

jue
 
U

Uri Guttman

GF> my $killrc = "sample.killrc";

GF> sub read_killrc {
GF> return unless open(my $file, "<$killrc") ;
GF> return map {
GF> /^([^#]+)#?$/ &&
GF> eval{ qr/$1/} || prompt $@, ()
GF> } <$file> ;
GF> }

some formatting/indenting will help there.
GF> read_killrc;

great! you just tossed away the results of the call.

GF> So, how do I adapt this now to take advantage of the return values of map?
GF> I no longer have the option of writing
GF> print @filter;

do you think print only takes an array? what does the above sub return?
A LIST generated by the map. so print it! you can print ANY expression
or list of expressions.

print read_killrc() ;

was that so hard? even with the flu you should have gotten that!

GF> # perl mats5.pl 2>text50.txt >text51.txt

GF> # perl mats7.pl 2>text50.txt >text51.txt
GF> This statement is what I call "the goocher." It keeps track of what version
GF> I'm running and has a means to redirect stdout and stderr. I should
GF> capitalize those. I copy and paste these into the command line.

that still makes no sense. the script (or at least the code you have
shown) doesn't print to STDERR.

GF> What kind of name is Uri?

my kind.

uri
 
A

A. Sinan Unur

I find this constant changing of posting ids pretty annoying. Please
decide if you are Wade Ward or zaxfux or whatever it is and stick with it.
In any case, you have been re-added to my killfile under this new identity
and I cannot believe I have been fooled into responding to your question.
GF> What kind of name is Uri?

What is the point of picking on other people's names when you can't even
decide what your own name is?

Sinan

--
A. Sinan Unur <[email protected]>
(remove .invalid and reverse each component for email address)

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

Jim Cochrane

JC> If I remember correctly, line 18 (from your error message) was either
JC> the offending line with the close curly brace missing the ';' or the
JC> line (print ...) below it. So you know where to look because of the
JC> line # in the error message. Of course, now that you know that 'do {}'
JC> blocks need a semicolon after them (right?), you know to look for that

actually do blocks are just expressions and the statement they might be
in will need a ; (and of course in perl ; is a statement separator and
not a terminator). in this case the do block was the end of the
statement and needed a ; before the print. an if block (or other flow
control block isn't a statement so they don't need ; after them.

uri

Thanks for the clarification.

--
 
J

Jim Cochrane

Gerry Ford said:
my $pat; eval ('$pat = qr/$_/') or do {prompt $@; next}; [...]

I'm still confused on the whole }; thing.

[good explanation deleted]

Also, see Uri Guttman's response to my post for further elaboration
(and correction to my somewhat misleading statement that you need a
semicolon after a do {} block).

--
 
C

Charlton Wilbur

ASU> I find this constant changing of posting ids pretty
ASU> annoying. Please decide if you are Wade Ward or zaxfux or
ASU> whatever it is and stick with it. In any case, you have been
ASU> re-added to my killfile under this new identity and I cannot
ASU> believe I have been fooled into responding to your question.

Pay attention to the posting style - it's consistent.

(I suspect his inability to write or program coherently and his
inability to stick to the same posting ID are both symptoms of a
deeper malaise.)

Charlton
 
G

Gordon Etly

A. Sinan Unur said:
What is the point of picking on other people's names when you can't
even decide what your own name is?

Why assume he was "picking" on him? I thought he meant it in the sense
of where the name comes from, what country/locale/etc? I don't see why
you had to immediately assume the poster was attempting an insult.
 
D

David Combs

--
"Life in Lubbock, Texas, taught me two things: One is that God loves you
and you're going to burn in hell. The other is that sex is the most
awful, filthy thing on earth and you should save it for someone you love."

~~ Butch Hancock

THAT is one good quotation to hang on the wall!


David
 

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,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top