Help with my brute force method

J

Jeff

I have a file (DM.txt) that has the following lines:


spool cr04 ip11 rm22
http web01 web02 web03
mail mail01 mail03


I want to create a variable ($Dis) that looks like this:

cr04|ip11|rm22

I was able to accomplish my goal, but it is ugly. I'm
sure there is a better way.

Here is my (brute force) code:

use strict;

my (@Lines,$Dis);
my $FILE="/tmp/DM.txt";

open (F, "< $FILE") || die "Can't open $FILE\n";
@Lines=grep /^spool/, <F>;
close(F);

($Dis=$Lines[0]) =~ s/spool //;
$Dis =~ s/ /\|/;
chomp($Dis);

exit;

I know it's ugly. It seems like I should be able to do something like:

($Dis = (split(grep /^spool/, <F>))[0]) =~ s/spool // =~ s/ /\|/;
But, I can't figure it out.

Please help.
 
J

John W. Krahn

Jeff said:
I have a file (DM.txt) that has the following lines:

spool cr04 ip11 rm22
http web01 web02 web03
mail mail01 mail03

I want to create a variable ($Dis) that looks like this:

cr04|ip11|rm22

I was able to accomplish my goal, but it is ugly. I'm
sure there is a better way.

Here is my (brute force) code:

use strict;

my (@Lines,$Dis);
my $FILE="/tmp/DM.txt";

open (F, "< $FILE") || die "Can't open $FILE\n";
@Lines=grep /^spool/, <F>;
close(F);

($Dis=$Lines[0]) =~ s/spool //;
$Dis =~ s/ /\|/;
chomp($Dis);

exit;

I know it's ugly. It seems like I should be able to do something like:

($Dis = (split(grep /^spool/, <F>))[0]) =~ s/spool // =~ s/ /\|/;
But, I can't figure it out.

Ah, you want to have all the code on one line.

open F, '<', $FILE or die "Can't open $FILE: $!";
my $Dis = join '|', map { my @a = split; /^spool/ ? @a[ 1 .. $#a ] : () } <F>;
close F;



John
 
A

Anno Siegel

Jeff said:
I have a file (DM.txt) that has the following lines:


spool cr04 ip11 rm22
http web01 web02 web03
mail mail01 mail03


I want to create a variable ($Dis) that looks like this:

cr04|ip11|rm22

I was able to accomplish my goal, but it is ugly. I'm
sure there is a better way.

Here is my (brute force) code:

use strict;

my (@Lines,$Dis);
my $FILE="/tmp/DM.txt";

open (F, "< $FILE") || die "Can't open $FILE\n";

You should include the error message $! in the text.
@Lines=grep /^spool/, <F>;

Since you are only expecting one line, this could be

( $line) = grep /^spool/ said:
close(F);

That is potentially inefficient. <f> in list context reads the
whole file into memory, but we need only the first line with /^spool/.
Also, grep() checks all the lines in the file, but again we could
stop at the first /^spool/.
($Dis=$Lines[0]) =~ s/spool //;
$Dis =~ s/ /\|/;

Did you test this? You need /g on the substitution.
chomp($Dis);

exit;

Untested:

open (F, "< $FILE") || die "Can't read file %FILE: $!";
my $Dis;
while ( <F> ) {
next unless ( $Dis) = /^spool (.*)/;
$dis s/ /\|/g;
last;
}

Anno
 
J

Jeff

Thanks, John.

I'm trying to grasp what's happening in your statement:

my $Dis = join '|', map { my @a = split; /^spool/ ? @a[ 1 .. $#a ] : ()
} <F>;

The join is going to insert the pipe character between each of the
strings returned by the map command.
The map is going to operate on each line in <F>
@a will be set to each element in the line

/^spool/ ? @a[1 .. $#a] : ()

This means that if the line starts with spool, return elements 1
through # elements, otherwise, return an empty array.

Correct?
 
J

John W. Krahn

Jeff said:
Thanks, John.

I'm trying to grasp what's happening in your statement:

my $Dis = join '|', map { my @a = split; /^spool/ ? @a[ 1 .. $#a ] : ()
} <F>;

The join is going to insert the pipe character between each of the
strings returned by the map command.
The map is going to operate on each line in <F>
@a will be set to each element in the line

/^spool/ ? @a[1 .. $#a] : ()

This means that if the line starts with spool, return elements 1
through # elements, otherwise, return an empty array.

Correct?

Correct. Of course it assumes that there is only one line that starts with
'spool'. :)


John
 
L

Larry Felton Johnson

Jeff said:
I have a file (DM.txt) that has the following lines:


spool cr04 ip11 rm22
http web01 web02 web03
mail mail01 mail03


I want to create a variable ($Dis) that looks like this:

cr04|ip11|rm22

If this file is always going to be this short efficiency isn't a
big concern, and for something this straightforward readability of
the code isn't really an issue, so I usually go with whatever my
fingers pound out, which was

use strict;

my $infile = "DM.txt";
open INFILE, "$infile" or die "Can't open $infile: $!\n";

my $Dis;
while (<INFILE>) {
if (/spool\s+(\w+)\s+(\w+)\s+(\w+)$/) {
$Dis = $1 . '|' . $2 . '|' . $3;
}
}

print "$Dis\n";
 
K

krakle

If this file is always going to be this short efficiency isn't a
big concern, and for something this straightforward readability of
the code isn't really an issue, so I usually go with whatever my
fingers pound out, which was

use strict;

my $infile = "DM.txt";
open INFILE, "$infile" or die "Can't open $infile: $!\n";

my $Dis;
while (<INFILE>) {
if (/spool\s+(\w+)\s+(\w+)\s+(\w+)$/) {
$Dis = $1 . '|' . $2 . '|' . $3;
}
}

print "$Dis\n";

Do you leave your home door wide open when you enter your house?
 
L

Larry Felton Johnson

(e-mail address removed) (krakle) wrote in message
Do you leave your home door wide open when you enter your house?

It depends on the weather, the time of year, whether I plan on being in
the front room for the evening, and a number of other factors :)

You wanna elaborate, or should I continue with domestic habit flow?

Larry
 
L

Larry Felton Johnson

(e-mail address removed) (krakle) wrote in message
Do you leave your home door wide open when you enter your house?

My intial off the cuff reply to this message didn't seem to post,
which is just as well, because I browsed back through the list to get
a representative sampling of the quality of your input.

My advice: it could use some work.

First of all your statement above is garbled. Is it in reference to
the code I posted? If so it'd be good to clearly refer to the code.
I don't normally comment on newsgroup/mailing list process issues, but
one obvious thing is that this is not a chat room, it's a language
related newsgroup. If you have a critique of any code or discussion
of code I post, say so, but do it clearly.
I'm not thin skinned ... rip into my code and tear it apart. Dazzle
me with your depth of knowledge of perl.

Metaphors are fine if they are clear and competent. The statement
above is neither.

Second, do you ever post code examples or evaluation of code? There's
nothing in the posts I've read to indicateMy intial off the cuff reply
to this message didn't seem to post, which is just as well, because I
browsed back through the list to get a representative sampling of the
quality of your input.

My advice: it could use some work.

First of all your statement above is garbled. Is it in reference to
the code I posted? If so it'd be good to clearly refer to the code.
I don't normally comment on newsgroup/mailing list process issues, but
one obvious thing is that this is not a chat room, it's a language
related newsgroup. If you have a critique of any code or discussion
of code I post, say so, but do it clearly.
I'm not thin skinned ... rip into my code and tear it apart. Dazzle
me with your depth of knowledge of perl.

Metaphors are fine if they are clear and competent. The statement
above is neither.

Second, do you ever post code examples or evaluation of code? There's
nothing in the posts I've read to indicate that you have even
rudimentary proficiency with perl. There's nothing to indicate you
don't either, but there are a handful of people here whose posts I
read carefully (even if I don't like their stylistic traits or
nettiquette). An orientation and focus on the problems and questions
at hand are one of the things which helps me devise my list of posters
worth reading.

I hope this is helpful. Your volume of posts indicates a great deal
of energy. If you'd work on channeling that energy in the service of
useful and constructive activity, it would serve both the perl
community and yourself much more effectively.

Now how about it? How does the one line code above relate to my
earlier post? that you have even rudimentary proficiency with perl.
There's nothing to indicate you don't either, but there are a handful
of people here whose posts I read carefully (even if I don't like
their stylistic traits or nettiquette). An orientation and focus on
the problems and questions at hand are one of the things which helps
me devise my list of posters
worth reading.

I hope this is helpful. Your volume of posts indicates a great deal
of energy. If you'd work on channeling that energy in the service of
useful and constructive activity, it would serve both the perl
community and yourself much more effectively.

Now how about it? How does the one line code above relate to my
earlier post?
 
L

Larry Felton Johnson

(e-mail address removed) (krakle) wrote in message
Do you leave your home door wide open when you enter your house?

(And speaking of garbled, if the feedback from my post is any
indication, my paragraphs got mangled somewhere in the editing or
posting process. Here is a second attempt:)

My intial off the cuff reply to this message didn't seem to post,
which is just as well, because I browsed back through the list to get
a representative sampling of the quality of your input.

My advice: it could use some work.

First of all your statement above is garbled. Is it in reference to
the code I posted? If so it'd be good to clearly refer to the code.
I don't normally comment on newsgroup/mailing list process issues, but
one obvious thing is that this is not a chat room, it's a language
related newsgroup. If you have a critique of any code or discussion
of code I post, say so, but do it clearly.
I'm not thin skinned ... rip into my code and tear it apart. Dazzle
me with your depth of knowledge of perl.
Metaphors are fine if they are clear and competent. Your statement
above was neither.


Second, do you ever post code examples or evaluation of code? There's
nothing in your posts I've read to indicate that you have even
rudimentary proficiency with perl. There's nothing to indicate you
don't either, but there are a handful of people here whose posts I
read carefully (even if I don't like their stylistic traits or
nettiquette). An orientation and focus on the problems and questions
at hand are one of the things which helps me devise my list of posters
worth reading.

I hope this is helpful. Your volume of posts indicates a great deal
of energy.
If you'd work on channeling that energy in the service of useful and
constructive activity, it would serve both the perl community and
yourself much more effectively.

So how about it? How does your one line comment above relate to my
earlier post?
 
K

krakle

(e-mail address removed) (krakle) wrote in message

It depends on the weather, the time of year, whether I plan on being in
the front room for the evening, and a number of other factors :)

You wanna elaborate, or should I continue with domestic habit flow?

Larry

Your other posts are too long to interest me. What I meant was...
close the opened file when you are done.. :)
 
A

Anno Siegel

krakle said:
(e-mail address removed) (Larry Felton Johnson) wrote in message


Your other posts are too long to interest me. What I meant was...
close the opened file when you are done.. :)

Why?

Anno
 
T

Tad McClellan

Anno Siegel said:


I can't think of a compelling reason in the context of a file
opened for _input_, as in this thread.

But I _always_ have an explicit close() because it cost me
six and a half hours of debugging once. [1]

The short version of the story: open()ed temp file for write,
chose OUT as the filehandle, days later, hundreds of lines of code later,
open()ed temp file for read, chose IN as the filehandle.

Bug: missing some output data near the end

Solution: add "close OUT" after writing temp file (flush buffer).



Just because Perl will do the Right Thing with an already-opened
filehandle does not mean that the Perl _programmer_ will do the
right thing!

It was a fixed-price job, I worked a whole day for nothing.

I found I didn't like that much. ;-)

Once bitten, twice shy, so:

1) I always use an explicit close()

2) I try to choose more descriptive filehandle names






[1] Which seems like a lot for somthing as simple as buffering, but
this was one of several thousand-line Perl programs run under
the control of a custom work flow manager. Much of the time
was just finding out _which_ Perl program had the bug.
 
A

Anno Siegel

Tad McClellan said:
Anno Siegel said:


I can't think of a compelling reason in the context of a file
opened for _input_, as in this thread.

But I _always_ have an explicit close() because it cost me
six and a half hours of debugging once. [1]

The short version of the story: open()ed temp file for write,
chose OUT as the filehandle, days later, hundreds of lines of code later,
open()ed temp file for read, chose IN as the filehandle.

Bug: missing some output data near the end

Solution: add "close OUT" after writing temp file (flush buffer).


[horror snipped]

Ah, you're right. When dealing with named file handles open for
writing you do have a point. Those are program-wide, and who
knows what might happen. I might even close a global read-handle.

Otherwise, lexical file handles close themselves when they go out of
scope. Together with the rule of making scopes as small as possible,
that takes care of it most of the time.

Anno
 
K

krakle

Tad McClellan said:
Anno Siegel said:
close the opened file when you are done.. :)

Why?


I can't think of a compelling reason in the context of a file
opened for _input_, as in this thread.

But I _always_ have an explicit close() because it cost me
six and a half hours of debugging once. [1]

The short version of the story: open()ed temp file for write,
chose OUT as the filehandle, days later, hundreds of lines of code later,
open()ed temp file for read, chose IN as the filehandle.

Bug: missing some output data near the end

Solution: add "close OUT" after writing temp file (flush buffer).


[horror snipped]

Ah, you're right. When dealing with named file handles open for
writing you do have a point. Those are program-wide, and who
knows what might happen. I might even close a global read-handle.

Otherwise, lexical file handles close themselves when they go out of
scope. Together with the rule of making scopes as small as possible,
that takes care of it most of the time.

Anno


Don't forget about mod_perl too... In my opinion it's proper to close
files that are opened...
 
B

Brian McCauley

krakle said:
(e-mail address removed)-berlin.de (Anno Siegel) wrote in message news:<[email protected]>...

Don't forget about mod_perl too... In my opinion it's proper to close
files that are opened...

Like Anno said, you should use lexical file handles so that they get
closed even on abnormal termination.
 
C

ctcgag

Tad McClellan said:
Anno Siegel said:
close the opened file when you are done.. :)

Why?


I can't think of a compelling reason in the context of a file
opened for _input_, as in this thread.

But I _always_ have an explicit close() because it cost me
six and a half hours of debugging once. [1]

The short version of the story: open()ed temp file for write,
chose OUT as the filehandle, days later, hundreds of lines of code
later, open()ed temp file for read, chose IN as the filehandle.

Bug: missing some output data near the end

Solution: add "close OUT" after writing temp file (flush buffer).

[horror snipped]

Ah, you're right. When dealing with named file handles open for
writing you do have a point. Those are program-wide, and who
knows what might happen. I might even close a global read-handle.

Otherwise, lexical file handles close themselves when they go out of
scope. Together with the rule of making scopes as small as possible,
that takes care of it most of the time.


However, the automatic closing does not die or warn upon failure.
If you open an actual file for reading, this probably isn't a problem,
but if you open a pipe command, it can be. Since one of the things I like
about perl the ready ability to change file opens into pipe opens, I am
careful to avoid situations where doing just that would create hard to find
bugs.

Xho
 

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,755
Messages
2,569,536
Members
45,008
Latest member
HaroldDark

Latest Threads

Top