Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

die function 1

Status
Not open for further replies.

vincebrown

Technical User
Apr 25, 2005
19
GB
Hi everyone. I'm trying to use the die function to throw an error when an inputted path is wrong, however it's not throwing anything. Can anyone tell me if the line of code below is correct:

open FILE, "$file" || die "Can't open: $! \n";

Thanks.
 
It's fine.
I think you'll find the problem is more the way you are trying to "catch" the error.

You need to execute the "open ... die" in an "eval". If the die occurs, execution will continue from the end of the eval block and the "die" message will appear in $@.

For example
Code:
eval {
    open FILE, "$file" || die "Can't open: $! \n";
    # Do other work here on open file
    close FILE;
};
if ($@) {
    if($@ =~ /Can't open:/) {
        # Handle file open failure here.
    } else {
        # Handle other errors here.
    }
}

Trojan


 
No, he doesn't need an eval for this. It's the binding of || that foiled him.

Either do

open FILE, "$file" or die "Can't open: $! \n";

(because or binds less tightly than ||)

or

open(FILE, "$file") || die "Can't open: $! \n";

(because the parens contain the open function)

Generally speaking it's a very good idea for new Perl folk to use "or" rather than "||" in conditional flow tests, and to use parens for functions. So (following both rules), I'd recommend getting used to writing that like this:

open(FILE, "$file") or die "Can't open: $! \n";

at least until you are very clear on what each of these does.

Tony Lawrence
Linux/Unix/Mac OS X Resources
 
However, Trojan is correct - you won't be able to catch it, as your script will die. If you do need to catch it and take some other action, then you will still need the eval. But with Tony's code inside it...
 
Forsome reason it still isn't working. Here's the code, any ideas?

#!/usr/bin/perl

print STDOUT "Please enter the full path of the make directory in your view (e.g.

C:\\cc\\views\\vb2659_view16\\leopard_system\\system-build\\make):\n";
$build = <STDIN>;
chomp $build;

print STDOUT "Please enter the name you would like to give your project:\n";
$name = <STDIN>;
chomp $name;

my $file = "$build\\MSVC.mk";

open (FILE, "$file") or die "Can't open: $! \n";
foreach(<FILE>){
push (@file,$_);
}
close FILE;
unlink $file;
open FILE, ">$file";
foreach (@file){
if ($_ =~ /CC /){
print FILE "CC = cpptest -Zcs -Zms"." $name.cpf "."-Zpc VC++6.0"."\n";
}elsif($_ =~ /CPP /){
print FILE "CPP = cpptest -Zcs -Zms"." $name.cpf "."-Zpc VC++6.0"."\n";
}elsif($_ =~ /THUMBCC /){
print FILE "THUMBCC = cpptest -Zcs -Zms"." $name.cpf "."-Zpc VC++6.0"."\n";
}elsif($_ =~ /THUMBCPP /){
print FILE "THUMBCPP = cpptest -Zcs -Zms"." $name.cpf "."-Zpc VC++6.0"."\n";
}else{
print FILE $_;
}
}
close FILE;

print STDOUT "$build\\MSVC.mk file updated.\n";

$file2 = "$build\\maketools.pl";

open FILE, "$file2";
foreach(<FILE>){
push (@file2,$_);
}
close FILE;
unlink $file2;
open FILE, ">$file2";
foreach (@file2){
if ($_ =~ /@ARGV\[2\]\)/){
print FILE "\t".' move(@ARGV[1], @ARGV[2]); # || die "MOVE failed: ".$!."\n"; '."\n";
}else{
print FILE $_;
}
}
close FILE;

print STDOUT "$build\\maketools.pl file updated.\n";
 
Well, what's not working?

There's a little confusion here maybe. You started out talking about "catching" and as was pointed out, you need an eval (or you can do it like this (the eval is cleaner, I think):

$myerrs="";
open (FILE, "$file") or $myerr=$!;
if ($myerr) {

# handle the error
print "There was an error opening $file: $myerr";
# whatever else you want to do
exit 0;

}

Now you give a bunch of code and say "it's not working". What isn't working? Catching the error? Updating your file? What are you trying to do?


Tony Lawrence
Linux/Unix/Mac OS X Resources
 
The question was originally about catching and the question is still about catching. I printed the code to put the catch in context.
 
What's happening that isn't supposed to, or what isn't happening that is supposed to?
 
The code you show doesn't have anything to "catch" - it's just going to die..

Two problems here: you need to do the open the way I showed you which you have done - but that answer wasn't to "catch" the error - your code wouldn't have noticed a failure at all.

To "catch" the error, you need an eval as TrojanWarBlade said or do it the way I showed with $myerr or whatever - if you use die outside of an eval, you just die..



Tony Lawrence
Linux/Unix/Mac OS X Resources
 
By "catching" I think he means he just wants to see what die returns if the file fails to open. The "catching" you are referring to is what I would call "trapping".

vincebrown:

you have another open() function you are not testing:

open FILE, "$file2";

and other system function you are not testing. It's a good idea to test all system function like open(), close(), unlink(), etc etc etc.
 
Yes, that's what threw me off too: when he first said it wasn't working,I thought he understood what die was and didn't know why it wasn't dieing - which was the || with the non-parened open.


If he wants the error, he has to use an eval or not use die and assign $! to something else for later use..

Probably confused the poor guy to death by now..



Tony Lawrence
Linux/Unix/Mac OS X Resources
 
Well, of course we try to bewilder. After all, I have a support based business - confusing people at the free forums adds to my paid business..

Just kidding.. but sometimes it almost seems that way.

Tony Lawrence
Linux/Unix/Mac OS X Resources
 
I'm not sure why everyone is insisting on an eval() to catch an open() error. open() returns false if it fails, so a simple if/else will catch an error:
Code:
 if ( open FILE, $file ) {

   print while ( <FILE> );

   close FILE;
}
else {
   warn "Error: $!\n";
}
 
Ishnid,

This was suggested earlier.
The "eval" explanation was more about how you catch a "die" than how you test the "open" but I agree, testing the result of open is much simpler and cleaner.

Trojan.

 
Lets take it from the begining.
You said
I'm trying to use the die function to throw an error when an inputted path is wrong, however it's not throwing anything.
now if you want to print an error message (by the time your script tries to open it), in case the file does not exist.......remember using this way your program will stop running
Code:
open FILE, "$file" or die "Can't open: $! \n";
if you want to print an error message later on on your script......
Code:
eval{
  open FILE, "$file" or die $!;
  do whatever
  close FILE:
};
if $! eq "No such file or directory"){
   print "Dude There is $!\n";
}
We put the if in case the $! holds something else that you didn't notice (usually something like [red]Inappropriate ioctl for device[/red]). So we check if it holds [red]No such file or directory[/red] which is the error message you get when the file does not exists. And you print whatever and whenever you want.
If your open function contains any '>' and the file does not exists, it will create it so there is no error as before.
If none of these ways are working for you then your perl is not the way she should be.

And something else, stop using [red]print STDOUT[/red] use just print and your message, it will print it to STDOUT, don't use in your code useless stuff


``The wise man doesn't give the right answers,
he poses the right questions.''
TIMTOWTDI
 
sorry in 'close FILE:' change the ':' with ';'
and place a '(' after 'if'.
I'm a little tired.


``The wise man doesn't give the right answers,
he poses the right questions.''
TIMTOWTDI
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top