ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I have a function in perl which I want to use trap all errors a script ocurs which the script does not explicitly handle. These errors are then logged to various places. So I tried to use a eval block but the problem I have is sometimes if you put a die statement in the evaled script it doesn't get handled. What I have so far is:
In Runner.pl:
Code:
eval qq{
require "$script";
start(\$defaults, \$dbparams, \$joblogger);
};
if ($@){
my $error = $@;
$joblogger->logCritical($error);
}
In testscript.pl:
Code:
use strict;
use warnings;
sub start{
my $defaults = shift;
my $dbparams = shift;
my $logger = shift;
die "I just wanna die";
}
The problem is that the $@ block doesn't happen. it justs exits silently. Does anybody why this should happen and what I need to do to fix it
You can't be posting the whole testscript.pl, because if you are, there should be a "1" on a line at the end of it. When I duplicated the problem without adding that "1", I got this output:
Code:
got an error: testscript.pl did not return a true value at (eval 1) line 1, <DATA> line 9.
When I put a "1" at the end and ran the whole thing I got:
Code:
got an error: I just wanna die at testscript.pl line 8, <DATA> line 10.
My revised script is at the end of this post. Try running on your system and examining the script itself. If that doesn't solve the problem, I can just two possible explanations:
There's another testscript.pl earlier in your @INC;
Your $joblogger is misbehaving; or (you weren't expecting the Spanish Inquisition, were you now)?
Everything's working fine, and you're looking for the output in all the wrong places.
Hope this helps. As Tiny Tim (no, not that Tiny Tim) would say, "God bless us, every 1."
Code:
#!/usr/bin/perl
unlink("testscript.pl");
open($phyle,">","testscript.pl");
while($in_line=<DATA>)
{
print($phyle "$in_line");
}
close($phyle);
$defaults = "mine and mine alone, all of them";
$dbparams = "db or not db, that is the question";
$joblogger = "Joe Blogger";
$script="testscript.pl";
eval qq{require "$script";
start(\$defaults, \$dbparams, \$joblogger);};
if($@)
{
print "got an error: $@";
}
__END__
use strict;
use warnings;
sub start{
my $defaults = shift;
my $dbparams = shift;
my $logger = shift;
die "I just wanna die";
}
1
I have a function in perl which I want to use trap all errors a script ocurs which the script does not explicitly handle. These errors are then logged to various places. So I tried to use a eval block but the problem I have is sometimes if you put a die statement in the evaled script it doesn't get handled. What I have so far is:
In Runner.pl:
Code:
eval qq{
require "$script";
start(\$defaults, \$dbparams, \$joblogger);
};
if ($@){
my $error = $@;
$joblogger->logCritical($error);
}
In testscript.pl:
Code:
use strict;
use warnings;
sub start{
my $defaults = shift;
my $dbparams = shift;
my $logger = shift;
die "I just wanna die";
}
The problem is that the $@ block doesn't happen. it justs exits silently. Does anybody why this should happen and what I need to do to fix it
A much better way is to use anonymous subroutine, and then you do not need to have '1' in the end:
Code:
sergei@amdam2:~/junk/hello_world_in_perl_with_eval> cat -n main.pl
1 #!/usr/bin/perl -w
2
3 use strict;
4 use warnings;
5
6 my $code_ref = eval {require './sub.prl'};
7
8 if($@)
9 {
10 warn "\$\@=$@";
11 }
12
13 $code_ref->('Perl programmer');
sergei@amdam2:~/junk/hello_world_in_perl_with_eval> cat -n sub.prl
1 use strict;
2 use warnings;
3
4 sub
5 {
6 my ($person) = @_;
7
8 warn "Hello, $person";
9 };
sergei@amdam2:~/junk/hello_world_in_perl_with_eval> ./main.pl
Hello, Perl programmer at ./sub.prl line 8.
sergei@amdam2:~/junk/hello_world_in_perl_with_eval>
OK I found it, one of the objects I was passing in had a a destroy method which has a function which resets $@. Very fiendish and evil I have to say . so I saved the error and reset it back after the troublesome piece of code. Thanks for the tip of the anonymous subs. Remembering to add 1 to the end was a bit tiresome
OK I found it, one of the objects I was passing in had a a destroy method which has a function which resets $@. Very fiendish and evil I have to say . so I saved the error and reset it back after the troublesome piece of code. Thanks for the tip of the anonymous subs. Remembering to add 1 to the end was a bit tiresome
Anonymity might feel somewhat alien to a Python programmer (I am judging from your nickname). But to me anonymity looks very friendly - this is because lack of name contention by construction. I.e. names are given (if any) in "consumer", i.e. at the assembly (in plain English sense) stage.
Sometimes names aren't even necessary - the code I posted was actually derived from this example:
Code:
sergei@amdam2:~/junk/hello_world_in_perl> cat -n main.pl
1 #!/usr/bin/perl -w
2
3 use strict;
4 use warnings;
5
6 (require './sub.prl')->('10speed705');
sergei@amdam2:~/junk/hello_world_in_perl> cat -n sub.prl
1 use strict;
2 use warnings;
3
4 sub
5 {
6 my ($person) = @_;
7
8 warn "Hello, $person";
9 };
sergei@amdam2:~/junk/hello_world_in_perl> ./main.pl
Hello, 10speed705 at ./sub.prl line 8.
sergei@amdam2:~/junk/hello_world_in_perl>
- in the above case truly anonymous code reference is dereferenced and called. "Perl is a damn good functional language" (c) OCaml tutorial.
Also 'require' creates an implicit scope, i.e. if a require'd file has lexical variables, they are all hidden from the "consumer" - a free and robust encapsulation. Nor code in the require'd file sees lexical variables of "consumer", i.e. also a good insulation layer.
...
The necessity to put "1;" is clearly documented:
perldoc -f require :
Code:
51 The file must return true as the last statement to indicate successful execution of any initialization code, so it's customary to end such a file with
52 "1;" unless you're sure it'll return true otherwise. But it's better just to put the "1;", in case you add more statements.
, so nothing is tiresome (except for not RTFMing).
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.