Discipulus has asked for the wisdom of the Perl Monks concerning the following question:

Many thanks to samtregar who replied to my 685965question and put me on the road of discovery of $^S

In first days of my adventure in Perl, I was reading almost montly the tantric page of the special variables thinking: 'mmh if i knew how to use all of them it will be a big advance..'

sam now point me to one of them, $^S ,it seemed to me not so usefull: 'if the state of the Perl interpreter is incorrect my little skills connot do nothing..'

Then I go to the docs and they say:
$^S Current state of the interpreter. $^S State --------- ------------------- undef Parsing module/eval true (1) Executing an eval false (0) Otherwise The first state may happen in $SIG{__DIE__} and $SIG{__WARN__} handler +s.
..and SuperSearch is my friend and it comes 607376, 315182 (where I dont well understand the ysth's reply) and 309692 where diotalevi and Aristotle point to another way to catching smarter..

So I wrote a little test script:
#!/usr/bin/perl use strict; use warnings; close STDERR; $|++; my $contaerrori= 0; $SIG{__WARN__} = sub { ++$contaerrori;print STDOUT "[WARN] ",@_ }; $SIG{__DIE__} = sub { print STDOUT "[CRITICAL ERROR]\t",@_; if ($^S == 1) { print "\tPerl interpreter + 1 (Executing an eval)\n\tCONTINUE RUNNING\n"} elsif ($^S == 0){ print "\tPerl interpreter + 0 (Otherwise)\n\tSTOP\n"} else { print "\tPerl interpreter un +def (Parsing module/eval)\n"} print "\n"; }; ###################################################################### +########## # HERE THE TESTS ###################################################################### +########## print "\nNATURAL END OF PROGRAM : ",$contaerrori," WARN",($contaerrori + eq 1 ? '' : 'S' )," IN $0\n";
The snippets to tests are the following:
#A print $a."\n"; #B require AAAAAA; #C eval { require BBBBB; } or do { warn " cannot load the mobule BBBBB \ +$^S = $^S\n"; print "\ttrying with another module: C +CCC\n\n"; eval { require CCCC; } or do {warn "ca +nnot load the mobule CCCC \$^S = $^S\n";}; if ( $@ ) {warn "no hope with modules +today..\n\n";die} else {print "\tsuccesfully loaded CCCC +\n" ;} }; #D eval { 0 } or do { warn "zero is not true \$^S = $^S\n"; }; #E eval { undef } or die "undef is not enough \$^S = $^S\n"; #F eval {require AAAAAA;}; if ($@) { local $SIG{'__DIE__'} = 'DEFAULT'; die "default die : $@"; }
These give this results:
#A [WARN] Use of uninitialized value in concatenation (.) or string at wa +rn-die.pl line 18. NATURAL END OF PROGRAM : 1 WARN IN warn-die.pl #B [CRITICAL ERROR] Can't locate AAAAAA.pm in @INC (@INC contains: C:/ +Perl/site/lib C:/Perl/lib .) at warn-die.pl line 20. Perl interpreter 0 (Otherwise) STOP #C [CRITICAL ERROR] Can't locate BBBBB.pm in @INC (@INC contains: C:/P +erl/site/lib C:/Perl/lib .) at warn-die.pl line 21. Perl interpreter 1 (Executing an eval) CONTINUE RUNNING [WARN] cannot load the mobule BBBBB $^S = 0 trying with another module: CCCC [CRITICAL ERROR] Can't locate CCCC.pm in @INC (@INC contains: C:/Pe +rl/site/lib C:/Perl/lib .) at warn-die.pl line 23. Perl interpreter 1 (Executing an eval) CONTINUE RUNNING [WARN] cannot load the mobule CCCC $^S = 0 [WARN] no hope with modules today.. [CRITICAL ERROR] Can't locate CCCC.pm in @INC (@INC contains: C:/Pe +rl/site/lib C:/Perl/lib .) at warn-die.pl line 23. ...propagated at warn-die.pl line 24. Perl interpreter 0 (Otherwise) STOP #D [WARN] zero is not true $^S = 0 NATURAL END OF PROGRAM : 1 WARN IN warn-die.pl #E [CRITICAL ERROR] undef is not enough $^S = 0 Perl interpreter 0 (Otherwise) STOP #F [CRITICAL ERROR]Can't locate AAAAAA.pm in @INC (@INC contains: C:/Perl +/site/lib C:/Perl/lib .) at warn-die.pl line 25. Perl interpreter 1 (Executing an eval) CONTINUE RUNNING
I think samtregar intended something like test #C when told me about error catching: when it fail to load the second module I choose to die normally and Perl says: ...propagated at warn-die.pl line 24.

In the #F test localize the handler to the DEFAULT seems not working.

is this the correct way to handle warn and die?
I remember somewhere is said that are "pseudo-signal", in which sense?

thank for the attention Lor*

Replies are listed 'Best First'.
Re: about redifining $SIG{'__DIE__'}
by moritz (Cardinal) on May 13, 2008 at 11:17 UTC
    I noticed that you tried to use the eval BLOCk form, not the the eval STRING form.

    Those two uses of eval are two quite different beasts, and I guess that $^S refers to the string form, not to the block form.

    Update Ok I tried it, I was wrong. Here's what's happening:

    use strict; use warnings; use Data::Dumper; print "in main: ", Dumper $^S; eval 'BEGIN { print "In eval STRING BEGIN: ", Dumper $^S; } print "in +eval STRING: ", Dumper $^S'; eval { BEGIN { print "in eval BLOCK BEGIN: ", Dumper $^S;} print "in eval BLOCK: ", Dumper $^S; }; __END__ in eval BLOCK BEGIN: $VAR1 = undef; in main: $VAR1 = '0'; In eval STRING BEGIN: $VAR1 = undef; in eval STRING: $VAR1 = '1'; in eval BLOCK: $VAR1 = '1';

    It turns out that $^S doesn't distinguish between BLOCK and STRING eval at all.