opening a file

G

George

Most people would suggest to use the three-argument form of open:
open INFILE, '<', 'nameoffile.txt';

Almost all people would strongly suggest to test for failure:
open INFILE, '<', 'nameoffile.txt' or
die "Cannot open nameoffile.txt because $!\n";

jue

Apparently, going out and getting drunk was exactly what this script
needed, as well as comments that helped.

open(50, '<eph4.txt');
DO:
{ my $line = readline(*50);
if(eof != 0) { exit }
print $line; # no 'write' here
redo DO } # no 'end' possible
close(50)

# perl faulk4.pl

C:\MinGW\source>perl faulk4.pl
Sun 18h 41m 55s -23â–‘ 5.4' 0.983 10.215 52.155 Up
Mercury 20h 2m 16s -22â–‘ 12.5' 1.102 22.537 37.668 Up
Venus 21h 55m 33s -14â–‘ 16.3' 0.795 39.872 11.703 Up
Moon 21h 17m 19s -15â–‘ 2.4' 62.4 ER 36.796 22.871 Up
Mars 18h 11m 59s -24â–‘ 6.1' 2.431 4.552 56.184 Up
Jupiter 20h 3m 35s -20â–‘ 49.4' 6.034 23.867 38.203 Up
Saturn 11h 32m 59s +5â–‘ 8.6' 9.018 -47.333 157.471 Set
Uranus 23h 21m 30s -4â–‘ 57.9' 20.421 48.328 -18.527 Up
Neptune 21h 39m 30s -14â–‘ 22.8' 30.748 38.963 16.599 Up

C:\MinGW\source>

Tja.
--
George

It's clearly a budget. It's got a lot of numbers in it.
George W. Bush

Picture of the Day http://apod.nasa.gov/apod/
 
P

Peter J. Holzer

I didn't know that.

Good for you. It's wrong.

The $_ variable isn't created by the while statement. It's a predefined
variable which always exists.

However, if you use the <> operator (or the readline function) inside
the condition of a while loop without explicitely assigning it to a
variable, the return value is automatically assigned to $_.


Thus
while (<FILE>) { .... }
and
while (readline(FILE)) { ... }
are just abbreviations for
while ($_ = <FILE>) { .... }
And this in turn is an abbreviation for
while (defined ($_ = <FILE>)) { .... }
because of another special case.

hp
 
T

Tad J McClellan

George said:
open(50, '<eph4.txt');


You should always, yes *always*, check the return value from open():

open(50, '<eph4.txt') or die "could not open 'eph4.txt' $!";
 
J

Jürgen Exner

Keith Keller said:
In the future if someone refers you to perldoc -q, it's a reference to
the FAQ, which is here:

http://perldoc.perl.org/perlfaq.html

Except that that may not be identical to the version installed on his
computer and applicable to his version of Perl.
The web site is ok, but it is better to install Perl properly including
perldoc and have the matching manuals available locally.

jue
 
J

Jürgen Exner

George said:
Apparently, going out and getting drunk was exactly what this script
needed, as well as comments that helped.

Do you actually read what people are writing before replying to a
posting?
open(50, '<eph4.txt');

Obviously not.

Again two argument form, again no test for failure (although it would
have cought the misspelled file name as evidenced in a different post).
DO:
{ my $line = readline(*50);
if(eof != 0) { exit }
print $line; # no 'write' here
redo DO } # no 'end' possible
close(50)

Again Fortran code disguised as Perl.

Ok, I had it. Bye bye, farewell, won't see you again.

jue
 
M

Mirco Wahab

George said:
Apparently, going out and getting drunk was exactly what this script
needed, as well as comments that helped.

open(50, '<eph4.txt');
DO:
{ my $line = readline(*50);
if(eof != 0) { exit }
print $line; # no 'write' here
redo DO } # no 'end' possible
close(50)

geaorge, *PLEASE* don't think this
above snippet would be anything useable
in Perl. It's a joke, nothing more.


The best thing would be to replace
this (faulk4.pl) completely by something
like the following code:

use strict;
use warnings;

my $filename = 'eph4.txt';
open my $filehandle, '<', $filename or die "$filename $!";

while( my $line = <$filehandle> ) {
print $line;
}
close $filehandle;


The same thing has bee suggested by
others too, several times. From *here*,
you'll be able to advance further -
but better not from the 'fortran-style'
thing I suggested last week for fun.

Regards

M.
 
G

George

Unfortunately is seems like George didn't get that joke :-(

jue

What joke? Mirco made the perl syntax match my previous notions, and when
you don't transpose letters in the filename, it works:


C:\MinGW\source>perl faulk4.pl
Sun 18h 41m 55s -23â–‘ 5.4' 0.983 10.215 52.155 Up
Mercury 20h 2m 16s -22â–‘ 12.5' 1.102 22.537 37.668 Up
Venus 21h 55m 33s -14â–‘ 16.3' 0.795 39.872 11.703 Up
Moon 21h 17m 19s -15â–‘ 2.4' 62.4 ER 36.796 22.871 Up
Mars 18h 11m 59s -24â–‘ 6.1' 2.431 4.552 56.184 Up
Jupiter 20h 3m 35s -20â–‘ 49.4' 6.034 23.867 38.203 Up
Saturn 11h 32m 59s +5â–‘ 8.6' 9.018 -47.333 157.471 Set
Uranus 23h 21m 30s -4â–‘ 57.9' 20.421 48.328 -18.527 Up
Neptune 21h 39m 30s -14â–‘ 22.8' 30.748 38.963 16.599 Up

C:\MinGW\source>type faulk4.pl

open(50, '<', 'eph4.txt') or die "cannot open";
DO:
{ my $line = readline(*50);
if(eof != 0) { exit }
print $line; # no 'write' here
redo DO } # no 'end' possible
close(50)

# perl faulk4.pl
C:\MinGW\source>

The thing I needed to do to make this work was step away from the machine.
You saw the transposition, and now I see that the io difficulties I was
having have disappeared.

For the sake of thoroughness, let me just list the scripts that I now have
for the identical purpose:


C:\MinGW\source>type faulk1.pl
#The manuals don't really say it but files have their own data type.
#This line creates a variable called file or exits saying that it can't
open
#the file with a possible explanation (the $! variable).
open( FILE, "eph4.txt") || die "Could not open ehp3.txt $!";

#read out one line at a time until the file ends
while( <FILE> ){
print $_; #If you don't specify a file it goes to STDOUT (STandard
OUTpu
t)
#The $_ variable is created by the while statement
}

close(FILE); #This might not really be needed

# perl faulk1.pl
C:\MinGW\source>type faulk2.pl
#!/usr/bin/perl
use strict;
use warnings;

my $filename = 'eph3.txt';
open my $handle, '<', $filename
or die "unable to open '$filename' because $!";
while (<$handle>) {
s/%%/%\n/;
print;
}
close $handle;

# perl faulk2.pl
C:\MinGW\source>type faulk7.pl
open(my $fh, '<', 'eph3.txt');
while (my $line = <$fh>) {
print $line;
}
close($fh)

# perl faulk7.pl
C:\MinGW\source>type faulk8.pl
open(my $fh, '<', 'eph3.txt');
while (<$fh>) {
print $_;
}
close($fh)

# perl faulk8.pl
C:\MinGW\source>type faulk9.pl
open(my $fh, '<', 'eph3.txt') or die "cannot open eph3.txt: $!";
while (<$fh>) {
print $_;
}
close($fh)

# perl faulk9.pl
C:\MinGW\source>type faulk10.pl
my $filename = 'eph3.txt';
open(my $fh, '<', $filename) or die "cannot open $filename: $!";
while (<$fh>) {
print $_;
}
close($fh)

# perl faulk10.pl
C:\MinGW\source>

Page 21 of the camel book is the reference a person needs for this. The
'<' means explicitly to read from an existing file.

Peter also gave two counterexamples to help illustrate what goes wrong:

C:\MinGW\source>perl faulk5.pl

C:\MinGW\source>type faulk5.pl
open(my $fh, '<eph3.txt>');
DO:
{ my $line = readline($fh);
if(eof != 0) { exit }
print $line;
redo DO }
close($fh)

# perl faulk5.pl
C:\MinGW\source> perl faulk6.pl

C:\MinGW\source>type faulk6.pl
open(my $fh, '<', 'eph3.txt>');
DO:
{ my $line = readline($fh);
if(eof != 0) { exit }
print $line;
redo DO }
close($fh)

# perl faulk6.pl
C:\MinGW\source>

Does someone have a reference for the three-argument form for open?

I'd like to thank everyone who responded to this thread; it was a learning
experience for me. But now that I have achieved this great thing, I'll
hope to process the file that gets opened.

Maybe I should start a new thread for that.
--
George

I think we ought to raise the age at which juveniles can have a gun.
George W. Bush

Picture of the Day http://apod.nasa.gov/apod/
 
P

Peter J. Holzer

What joke? Mirco made the perl syntax match my previous notions,

This is the joke. He wrote completely unidiomatic (and quite horrible)
Perl which looks almost like Fortran, alluding to the well-known joke
that "real programmers can write Fortran programs in any language"[1]
(which you cited yourself earlier in the thread).
and [...] it works:

That makes it even funnier.

hp

[1] Real Programmers Don't Use Pascal. Ed Post, Tektronix, Wilsonville
OR, USA. Letter to the editor of Datamation, volume 29 number 7,
July 1983.
http://www.pbm.com/~lindahl/real.programmers.html
 
G

George

Files do NOT have their own data type.

Filehandles have their own data type though.
ok


This line creates a filehandle called FILE.

Case matters.
ok
^^
^^ oops yet again...

But in modern perls, using a lexical filehandle, along with the 3-arg
form of open() is much much better, so you might as well learn the
best way rather than the anachronistic way:

open( my $FILE, '<', 'eph4.txt') || die "Could not open 'eph4.txt' $!";

or, without superfluous punctuation:

open my $FILE, '<', 'eph4.txt' or die "Could not open 'eph4.txt' $!";

But I think you have to go Peter's notion that you want your script to tell
you *exactly* what file you asked for:

my $filename = 'eph3.txt';
open(my $fh, '<', $filename) or die "cannot open $filename: $!";

How does $filename: $! become eph3.txt, when the OS can't find it?
The $_ variable is NOT created by the while statement.

The $_ variable is populated by the while statement though.
ok


But it is always a good idea, else you are likely to forget
one of those rare times where it really is needed.

A tale of woe where _I_ forgot once, and worked all day for no pay:

http://groups.google.com/groups/[email protected]

That's good reading. I call that "biting my tail" programming. If you
ever have an ecumenical discussion with a fortran guy, you could explain
the filehandles as unit numbers. For fortran, they are nonnegative
integers with 5 as stdin and 6 as stdout. We recommend explicit closes as
well.

Much better! :)

I'd like to say "shucks," but I don't know what $! does.
There are 3 "Page 21 of the camel book", since there are 3 editions
of the book...

Mine's current.
Books are only supplemental references, you consult them if the
primary references for Perl does not satisfy.

Simply reading the std docs for the functions you are using is
often enough.




perldoc -f open

If MODE is '<' or nothing, the file is opened for input.




Everyone who has perl has a reference for the three-argument form for open:

perldoc -f open

If three or more arguments are specified then ...

I pulled some of this material out:

You may also, in the Bourne shell tradition, specify an EXPR
beginning with '>&', in which case the rest of the string is
interpreted as the name of a filehandle (or file descriptor, if
numeric) to be duped (as dup(2)) and opened. You may use "&"
after ">", ">>", "<", "+>", "+>>", and "+<". The mode you
specify should match the mode of the original filehandle.
(Duping a filehandle does not take into account any existing
contents of IO buffers.) If you use the 3-arg form then you can
pass either a number, the name of a filehandle or the normal
"reference to a glob".

open FILEHANDLE,MODE,EXPR

open FILEHANDLE,MODE,REFERENCE

As a special case the 3-arg form with a read/write mode and the
third argument being "undef":

open(TMP, "+>", undef) or die ...

opens a filehandle to an anonymous temporary file. Also using
"+<" works for symmetry, but you really should consider writing
something to the temporary file first. You will need to seek()
to do the reading.

How does perl.exe know whether the third argument is an expression or a
reference?
--
George

The men and women of Afghanistan are building a nation that is free, and
proud, and fighting terror - and America is honored to be their friend.
George W. Bush

Picture of the Day http://apod.nasa.gov/apod/
 
G

George

What joke? Mirco made the perl syntax match my previous notions,

This is the joke. He wrote completely unidiomatic (and quite horrible)
Perl which looks almost like Fortran, alluding to the well-known joke
that "real programmers can write Fortran programs in any language"[1]
(which you cited yourself earlier in the thread).

Real programmers, like clf's Catherine Zeta Lay, express what I precisely
meant in german:

Wir meinen damit daß das abwertend ist, fortran sonstwo zu üben.

This translates as:

We mean that the pejorative is fortran elsewhere to practice.
and [...] it works:

That makes it even funnier.

hp

[1] Real Programmers Don't Use Pascal. Ed Post, Tektronix, Wilsonville
OR, USA. Letter to the editor of Datamation, volume 29 number 7,
July 1983.
http://www.pbm.com/~lindahl/real.programmers.html

I know Greg! I was programming in 1983 for the Man who taught me
everything: Leroy Wentz.

Greg is a subscriber to the "big tent" inclusion ethos of
comp.lang.fortran: the topic always seems to return when we are civil.
--
George

The course of this conflict is not known, yet its outcome is certain.
Freedom and fear, justice and cruelty, have always been at war, and we know
that God is not neutral between them.
George W. Bush

Picture of the Day http://apod.nasa.gov/apod/
 
T

Tad J McClellan

George said:
But I think you have to go Peter's notion that you want your script to tell
you *exactly* what file you asked for:


Excellent idea.

my $filename = 'eph3.txt';
open(my $fh, '<', $filename) or die "cannot open $filename: $!";

How does $filename: $! become eph3.txt, when the OS can't find it?


I do not understand your question.

If the file cannout be found, you'll get output something like:

cannot open eph3.txt: File not found

I'd like to say "shucks," but I don't know what $! does.


It is a Perl variable.

All of Perl's variables are documented in:

perldoc perlvar

I don't remember what fortran called it, but Perl's $! is errno in C.

If used as a string rather than a number, then perl will look up
that error number for you, and its value will be "permission denied"
or "file not found" or some such.

How does perl.exe know whether the third argument is an expression or a
reference?


perldoc -f ref
 
P

Peter J. Holzer

What joke? Mirco made the perl syntax match my previous notions,

This is the joke. He wrote completely unidiomatic (and quite horrible)
Perl which looks almost like Fortran, alluding to the well-known joke
that "real programmers can write Fortran programs in any language"[1]
(which you cited yourself earlier in the thread).

Real programmers, like clf's Catherine Zeta Lay, express what I precisely
meant in german:

Wir meinen damit daß das abwertend ist, fortran sonstwo zu üben.

This translates as:

We mean that the pejorative is fortran elsewhere to practice.

Your translation isn't correct, but it's quite good at a meta level: It
sounds about as wrong in English as the original sounds wrong in German.
I don't know Catherine, much less how how good her German is, but I see
two possibilities:

1) Her German isn't very good.

2) Her German is very good and she made errors on purpose to make the
point: To me as a German speaker the sentence sounds about as wrong
as Mirco's script looks wrong to me as a Perl programmer. No German
speaker would say this sentence (except as a parody on non-native
Speakers) and no Perl programmer would write a script like Mirco's
(except as a parody on Fortran). Just like you can't translate
literally from one natural language to another word by word, you
can't translate literally from one programming language to another.
The result may "work", but it isn't pretty.

hp
 
G

George

All of Perl's variables are documented in:

perldoc perlvar

I don't remember what fortran called it, but Perl's $! is errno in C.

If used as a string rather than a number, then perl will look up
that error number for you, and its value will be "permission denied"
or "file not found" or some such.

There's a lot to learn there. What a motley crüe of variables comes with
the porridge in perl!

This is pretty straightforward:


$! If used numerically, yields the current value of the C "errno"
variable, or in other words, if a system or library call fails,
it sets this variable. This means that the value of $! is
meaningful only *immediately* after a failure:

if (open(FH, $filename)) {
# Here $! is meaningless.
...
} else {
# ONLY here is $! meaningful.
...
# Already here $! might be meaningless.
}
# Since here we might have either success or failure,
# here $! is meaningless.

In the above *meaningless* stands for anything: zero, non-zero,
"undef". A successful system or library call does not set the
variable to zero.

If used as a string, yields the corresponding system error
string. You can assign a number to $! to set *errno* if, for
instance, you want "$!" to return the string for error *n*, or
you want to set the exit value for the die() operator.
(Mnemonic: What just went bang?)

I don't get the mnemonic.
perldoc -f ref

ref EXPR
ref Returns a non-empty string if EXPR is a reference, the empty
string otherwise. If EXPR is not specified, $_ will be used.
The value returned depends on the type of thing the reference is a
reference to. Builtin types include:
# end excerpt

I don't see this at all.

open FILEHANDLE,MODE,EXPR
open FILEHANDLE,MODE,REFERENCE

Is this the difference between:

open(my $fh, '<', 'eph3.txt');
open(my $fh, '<', $filename);
?


--
George

I sent American troops to Iraq to make its people free, not to make them
American. Iraqis will write their own history and find their own way.
George W. Bush

Picture of the Day http://apod.nasa.gov/apod/
 
J

Jim Gibson

George said:
On Sun, 11 Jan 2009 22:38:58 -0600, Tad J McClellan wrote:
$! If used numerically, yields the current value of the C "errno"
....

(Mnemonic: What just went bang?)

I don't get the mnemonic.

"bang" is the common, short-form name of the "exclamation-point"
character '!'. Thus, the string '#!' is read as "pound bang", "hash
bang", or colloquially as "she-bang" (not sure about the derivation of
the last).
 
E

Eric Pozharski

ref EXPR
ref Returns a non-empty string if EXPR is a reference, the empty
string otherwise. If EXPR is not specified, $_ will be used.
The value returned depends on the type of thing the reference is a
reference to. Builtin types include:
# end excerpt

I don't see this at all.

open FILEHANDLE,MODE,EXPR
open FILEHANDLE,MODE,REFERENCE

Is this the difference between:

open(my $fh, '<', 'eph3.txt');
open(my $fh, '<', $filename);
?

C<'eph3.txt'> is literal; C<$filename> is scalar; both are expressions;
expressions aren't limited to scalars and literals.
C<perldoc perlglossary> has more.
 
G

George

Your translation isn't correct, but it's quite good at a meta level: It
sounds about as wrong in English as the original sounds wrong in German.
I don't know Catherine, much less how how good her German is, but I see
two possibilities:

1) Her German isn't very good.

2) Her German is very good and she made errors on purpose to make the
point: To me as a German speaker the sentence sounds about as wrong
as Mirco's script looks wrong to me as a Perl programmer. No German
speaker would say this sentence (except as a parody on non-native
Speakers) and no Perl programmer would write a script like Mirco's
(except as a parody on Fortran). Just like you can't translate
literally from one natural language to another word by word, you
can't translate literally from one programming language to another.
The result may "work", but it isn't pretty.

I think you misunderestimate my ability to adhere to an idiom, but I took a
gander at Duden 2: Stilwörterbuch to see what the definitive german
reference has to say.

In § V 2 they list the Nuancierungen:
scherzhaft
ironisch
abwertend
nachdrücklich
verhüllend
, where "abwertend" kennzeichnet eine Aussage, die ein ablehnendes Urteil
enthält: Schiebung, Wisch.

Whatever joke there was has clearly waned, but I have one more question
about this material. Earlier you advised to use lexical filehandles,
something like:

open(my $fh, '<', $filename) or die "cannot open $filename: $!";

In chapter one of the camel book in the filehandles section, it just uses:

open(SESAME, "filename");

How does this differ from

open(my $SESAME, "filename");

, and does it make a difference?
--
George

On September 11 2001, America felt its vulnerability even to threats that
gather on the other side of the Earth. We resolved then, and we are
resolved today, to confront every threat from any source that could bring
sudden terror and suffering to America.
George W. Bush

Picture of the Day http://apod.nasa.gov/apod/
 
T

Tim Greer

George said:
Whatever joke there was has clearly waned, but I have one more
question about this material.  Earlier you advised to use lexical
filehandles, something like:

open(my $fh, '<', $filename) or die "cannot open $filename: $!";

In chapter one of the camel book in the filehandles section, it just
uses:

open(SESAME, "filename");

How does this differ from

open(my $SESAME, "filename");

, and does it make a difference?

The three argument method is simply the preferred way now. Things
evolve over time and this has become the preferred method for many.
There's really not a difference in a matter of speaking, it can just
make things easier down the road. Having an argument for the
redirection character can sometimes make you think about what you're
doing and specifically specify the redirect character you want to use.

For example, instead of open(FILE, "file") or die $!, where it's opening
for 'read' by default, you tell it to specifically read open my
$filehandle, '<', "filename" or die $!. I've seen a lot of people ask
why their files weren't updated and they didn't recall to add the
proper redirect character (>, >>, or whatever) to their open function.
You can use whichever you feel more confortable with. You should still
check if it was successful and report the failure (and why) if not.
 
T

Tim Greer

Tim said:
The three argument method is simply the preferred way now. Things
evolve over time and this has become the preferred method for many.
There's really not a difference in a matter of speaking, it can just
make things easier down the road. Having an argument for the
redirection character can sometimes make you think about what you're
doing and specifically specify the redirect character you want to use.

For example, instead of open(FILE, "file") or die $!, where it's
opening for 'read' by default, you tell it to specifically read open
my
$filehandle, '<', "filename" or die $!. I've seen a lot of people ask
why their files weren't updated and they didn't recall to add the
proper redirect character (>, >>, or whatever) to their open function.
You can use whichever you feel more confortable with. You should
still check if it was successful and report the failure (and why) if
not.

I misspoke that there are really no differences, as there actually are,
depending on the scenario. Also, I should have actually added more
details about indirect file handles above. However, instead of
repeating a few of the advantages to the three-argument open and
indirect file handles, please refer to
perldoc -f open (on the web at
http://perldoc.perl.org/functions/open.html)

As well as, you can get read up quickly at:
http://perldoc.perl.org/perlopentut.html Specifically, refer to
"Simple Opens" and the latter mentioned 3-argument version. Directly
below is "Indirect Filehandles", which you should find of particular
interest. These outline the differences, again depending on the
scenario and provide all of the gory details.
 
C

cartercc

You should always, yes *always*, check the return value from open():

Like other ironclad rules, this also has exceptions. Using the 'or
die' construct has costs (albeit minimal) and when the costs outweigh
the benefit, you shouldn't use it. Example: opening the file is
tangential to the script so you don't care whether the file opens but
you DO care if the script dies.

It's true that in the vast majority of cases a prudent script will
perform error checking for open(), but it's also true that one
shouldn't follow the rule blindly forgetting the purpose and the
effects of error checking.

CC
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top