LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-08-2010, 09:48 AM   #1
pgpython
Member
 
Registered: Dec 2005
Location: Sheffield, UK
Distribution: Gentoo
Posts: 142

Rep: Reputation: 32
Problem with perl die and eval


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
 
Old 11-08-2010, 01:11 PM   #2
wje_lq
Member
 
Registered: Sep 2007
Location: Mariposa
Distribution: FreeBSD,Debian wheezy
Posts: 811

Rep: Reputation: 179Reputation: 179
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:
  1. There's another testscript.pl earlier in your @INC;
  2. Your $joblogger is misbehaving; or (you weren't expecting the Spanish Inquisition, were you now)?
  3. 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
 
1 members found this post helpful.
Old 11-08-2010, 01:37 PM   #3
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by pgpython View Post
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>
.
 
1 members found this post helpful.
Old 11-09-2010, 05:00 AM   #4
pgpython
Member
 
Registered: Dec 2005
Location: Sheffield, UK
Distribution: Gentoo
Posts: 142

Original Poster
Rep: Reputation: 32
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
 
Old 11-09-2010, 06:00 AM   #5
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by pgpython View Post
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).
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: Open source must die die die LXer Syndicated Linux News 0 01-28-2006 08:16 PM
Suse 9.3 eval cd 1 checksum problem hyapadi SUSE / openSUSE 3 07-05-2005 07:56 AM
Die, lotus notes, die (sorry for ranting) slackist General 10 01-10-2005 10:42 AM
SuSE 9.1 live eval cd problem redfedora88 Linux - Newbie 1 10-09-2004 10:35 PM
Die Caps lock Die! tfdml37 Linux - General 1 06-26-2004 02:00 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:06 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration