Re: Carp::nosigdie - needs a better name
From: Eric Wilhelm [EMAIL PROTECTED] I found myself wanting to check whether some code had a $SIG{__DIE__} in it and realized I still had this silly module in my experiments directory. This throws an error whenever a $SIG{__DIE__} is assigned without a local(). Potentially useful in tests, or just via -M... (Yes, actually it throws an error when it gets deleted, but the point is to catch itself getting replaced.) That seems like it might be useful on CPAN and I'm not finding anything in a search, so it just needs a name? I thought about adding more features, but then that would just be feature creep. Should it be in Devel::? package Carp::NoSigDie; snipped Thoughts? Why not make it slightly more general? - package CarpIfForgotten; use strict; require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(makeSubThatCarpsIfForgotten); use Carp; use warnings; my $ended = 0; END {$ended = 1;}; sub makeSubThatCarpsIfForgotten { my ($msg, $behaviour) = @_; my $obj = {}; my $pkg = 'CarpOnDESTROY' . (0+\$obj); { no strict 'refs'; *{$pkg.'::DESTROY'} = sub { return if $ended; Carp::carp($msg) }; } $obj = bless $obj, $pkg; if ($behaviour) { return sub { my $foo = $obj; # to keep a reference goto $behaviour } } else { return sub { my $foo = $obj; # to keep a reference return; } } } 1; - # test1.pl use CarpIfForgotten; our $sub1 = makeSubThatCarpsIfForgotten( 'sub1 disappeared', sub {print sub1 called\n}); our $sub2 = makeSubThatCarpsIfForgotten( 'sub2 disappeared', sub {print sub2 called\n}); our $sub3 = makeSubThatCarpsIfForgotten( 'sub3 disappeared'); print All set\n; $sub1-(); $sub2-(); $sub3-(); print All called\n; undef $sub2; print Sub1 destroyed\n; sleep(1); $sub1-(); $sub3-(); print Others called\n; - # test2.pl use CarpIfForgotten; $SIG{__DIE__} = makeSubThatCarpsIfForgotten('someone changed the __DIE__ handler!'); print Set\n; $SIG{__DIE__} = undef; print ReSet\n; - There's a catch though ... if the $subN variables are 'my' instead of 'our' they are destroyed before the END{} block runs! Also if the '$SIG{__DIE__} = undef;' is the last statement that runs, you are not warned. Before uploading to CPAN I'd allow specifying a subroutine to call in place of the message that is to be carp()ed. Jenda = [EMAIL PROTECTED] === http://Jenda.Krynicky.cz = When it comes to wine, women and song, wizards are allowed to get drunk and croon as much as they like. -- Terry Pratchett in Sourcery
Re: Carp::nosigdie - needs a better name
On Wed, Sep 03, 2008 at 12:29:01AM -0700, Eric Wilhelm wrote: package Carp::NoSigDie; use warnings; use strict; use Carp (); use overload '{}' = sub {sub {}}, fallback = 1; $SIG{__DIE__} = bless({}, __PACKAGE__); my $ended = 0; END {$ended = 1}; sub DESTROY { return if($ended); Carp::carp(bad bunny); exit(1); } 1; Thoughts? From the code, I would have no idea what this does without a fair bit of perldoc-ing. How about some comments? bad bunny? Well, you asked. Austin
Re: Carp::nosigdie - needs a better name
# from Austin Schutz # on Wednesday 03 September 2008 11:41: From the code, I would have no idea what this does without a fair bit of perldoc-ing. How about some comments? bad bunny? Oh, so you want features? I'm not sure what constitutes a fair bit of documentation though =head1 ABOUT Throws an error if any code sets $SIG{__DIE__} (other than with local().) This allows you to detect misbehaving code which might e.g. call exit() from within an eval {}. =head1 USAGE perl -MCarp::nosigdie yourprogram.pl =head1 SEE ALSO Lperlvar/$^S, Lperlvar/%SIG, and Lperlfunc/die =cut Yeah, the message: BZZT: non-localized $SIG{__DIE__} assignment at foo.pm line ... would probably be more useful than: bad bunny at foo.pm line... Sure. And possibly even installing your own global die handler via import() would be nifty too. So Carp::nosigdie is a good name then? Thanks, Eric -- ...our schools have been scientifically designed to prevent overeducation from happening. --William Troy Harris --- http://scratchcomputing.com ---
Re: Carp::nosigdie - needs a better name
# from David Nicol # on Wednesday 03 September 2008 11:30: it could be documented as a suggested use case for Acme::Landmine Acme::landmine uses tie (on %SIG - does that work?) to blow up when the variable is accessed, but I only want to know when it is globally deleted. How does that work? Also, as a debugging tool, I would rather be able to just load the module from a perl option. --Eric -- Introducing change is like pulling off a bandage: the pain is a memory almost as soon as you feel it. --Paul Graham --- http://scratchcomputing.com ---
Re: Carp::nosigdie - needs a better name
On Wed, 3 Sep 2008, Eric Wilhelm wrote: Acme::landmine uses tie (on %SIG - does that work?) to blow up when the Yes, tying %SIG is possible, and even tying entries in the %SIG hash. See Sig::PackageScoped for an entirely insane example. http://search.cpan.org/~drolsky/Sig-PackageScoped-0.04/ -dave /*== VegGuide.Org Your guide to all that's veg ==*/
Re: Carp::nosigdie - needs a better name
On Wed, Sep 3, 2008 at 3:12 PM, Eric Wilhelm [EMAIL PROTECTED] wrote: Also, as a debugging tool, I would rather be able to just load the module from a perl option. yes, absolutely. Until I saw your usage example I did not get how you use this handy tool. Since the localizing is the thing you are trying to catch, how about including that in the new, improved name? Furthermore, you're enforcing a stricture, rather than enhancing Carp. Here's a briefly considered suggestion: perl -Mstrict::sigdie yourprogram.pl Maybe some day this will be a best practice: use strict; use strict::sig::die; calling it strict::sig::die opens up the strict::sig:: space for future development of pragmata that enforce strictures about other entries in %SIG, too. hopefully the amount of wind that leaks in after this opening of the door to discussion of best practices and $SIG{__DIE__} will not be unmanageable.
Re: Carp::nosigdie - needs a better name
# from David Nicol # on Wednesday 03 September 2008 13:29: Furthermore, you're enforcing a stricture, rather than enhancing Carp. Here's a briefly considered suggestion: perl -Mstrict::sigdie yourprogram.pl Maybe some day this will be a best practice: use strict; use strict::sig::die; calling it strict::sig::die opens up the strict::sig:: space for future development of pragmata that enforce strictures about other entries in %SIG, too. True, though I would rather that it not need to be a standard practice. Any code I write isn't going to install a global die handler without really good reason, so it is more useful in checking for action at a distance than watching over me. But: Put it in all of your tests or as a harness option? Sure. Wherever you're concerned about weird stuff creeping in. But put it in all of your cpan modules? No. That's just too much nannyism and because of the global-at-a-distance nature it would be at least as bad as the thing it is meant to detect. David Cantrell suggested Devel::NoGlobalSigDie, which fits, but I think that's maybe a lot to pound in after -M (or -d: for that matter.) What about Devel::no::sigdie? I get his point about the global, but maybe it could just be an option. Devel::NoSigDie is too much shifting? --Eric -- ...the bourgeoisie were hated from both ends: by the proles, because they had all the money, and by the intelligentsia, because of their tendency to spend it on lawn ornaments. --Neal Stephenson --- http://scratchcomputing.com ---