I am having a problem I can't seem to figure out and I hope you guys can help me.
The problem occurs when :
Example:
Main file
use strict;
use warnings;
# signal handling
$SIG{__DIE__} = sub {
my $error = @_;
chomp $error;
print "die: $error\n";
};
require mod;
mod->get_stat();
Module
package mod;
use strict;
use warnings;
use File::stat;
sub get_stat {
my $file_path = "test.txt";
my $file_size = stat($file_path)->size;
print $file_size;
}
1;
This will cause the following output:
die: 1
die: 1
die: 1
die: 1
die: 1
4
Now, if I remove my custom error handling OR if I use mod instead of require the die's will not be displayed.
Interesting to see is that it does actually produce a result (test.txt is 4 bytes), meaning stat is working as it should.
So, why am I getting this error ? Is this really an error ? Does the default perl error handling ignore errors that are "1"?
EDIT
As Linus Kleen remarked, the reason I get "1" is because I am displaying the amount of elements in the array.
If I print out the content of the error instead, I get the following error:
die: Your vendor has not defined Fcntl macro S_ISVTX, used at c:/Perl64/lib/File/stat.pm line 37.
die: Your vendor has not defined Fcntl macro S_IFSOCK, used at c:/Perl64/lib/File/stat.pm line 41.
die: Your vendor has not defined Fcntl macro S_IFBLK, used at c:/Perl64/lib/File/stat.pm line 41.
die: S_IFFIFO is not a valid Fcntl macro at c:/Perl64/lib/File/stat.pm line 41.
die: Your vendor has not defined Fcntl macro S_IFLNK, used at c:/Perl64/lib/File/stat.pm line 41.
4
But still, I am getting an error that, without custom error handling, I do not get.
As explained in perlvar, due to an implementation glitch $SIG{__DIE__}
hooks get called even when code dies inside an eval. When File::stat is loaded, it checks to see what constants Fcntl supports on your platform. It catches the errors caused by unsupported constants, but not before your hook sees them.
You can tell if you're in an eval
by checking the value of $^S
. If it's not 0, then you're in an eval.
$SIG{__DIE__} = sub {
return unless defined $^S and $^S == 0; # Ignore errors in eval
my ($error) = @_;
chomp $error;
print "die: $error\n";
};
You don't see the errors when you use
instead of require
because use
is a compile-time operation and require
is a run-time operation (as is setting %SIG
). When you use mod
and it use
s File::stat, that all happens before you set up your hook. When you require mod
, that doesn't happen until after you've installed your hook.