views:

56

answers:

2

I want to do some task when the file is not opened in the Perl program below. But when I run it, I am getting syntax errors. What's wrong with it?

my $LOGPATH = $ENV{DATA_OU};
my $LOGFILE =  "cdj_rep" . "." . "test" . ".rpt";

if ! (open(OUT,">$LOGPATH/test1/work/$LOGFILE")) {
   print "testin";
   return;  
}

close(OUT);
+5  A: 

The ! needs to go inside the brackets:

if (! open (out,
Kinopiko
Thanks a lot for the info
Arav
+7  A: 

I'd write it as

my $LOGPATH = $ENV{DATA_OU};
my $LOGFILE = "cdj_rep.test.rpt";
my $path    = "$LOGPATH/test1/work/$LOGFILE";

open my $fh, ">", $path or do {
  warn "$0: open $path: $!";
  return;
};

close $fh or warn "$0: close $path: $!";

Place the entire path in $path so you don't have to repeat it multiple times, and if you ever need to change it, you can do so in one place.

The call to open uses a lexical filehandle (my $fh) rather than a bareword handle. This is a good habit to develop because passing $fh to subs or stuffing it inside data structures tends to be more natural syntactically.

It also uses the 3-argument form of open so you don't have to worry about characters in the path being interpreted specially. It may not seem like a big deal in the context of your code, but it's another good habit to develop.

A common idiom for checking whether an open succeeds is

open my $fh, "<", $path
  or die "$0: open $path: $!";

Using if (!open ... or unless (open ... would be fine, but with a lexical filehandle, you need to worry about scoping issues. You seem to be using the check as a guard, so writing open or ... leaves the filehandle in scope for when it does succeed. You want two statements to execute if it fails, so you need to wrap them in do { ... } as above.

Also note the content of the error message passed to warn:

  • the program that had an error ($0)
  • what it was trying to do (open $path)
  • and why it failed ($!)

The warn and die operators send their output to the standard error, which allows the flexibility of redirecting error messages elsewhere.

Finally, when you close a handle on a file you created to write or append, you should check whether it fails, which might happen if an I/O error occurred, for example.

Greg Bacon
Schwern says we should use `autodie`.
Kinopiko
+1: well written recommendation for the newer, better Perl open techniques.
drewk