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

Greetings monks.

I have a framework (say Foo::Bar) with many modules that report errors through a method in Foo::Bar::Error.

As I want to report errors from the perspective of the user, I'm using Carp, and setting @Foo::Bar::Error::CARP_NOT to the complete list of modules under, and including Foo::Bar.

Unfortunately this list of modules is constantly changing and its easy to get @CARP_NOT out of sync.

Are there any pre-existing solutions to this problem, or am I going to have to pratt around with stack traces or generate the complete list of Foo::Bar modules by hand whenever it changes?

Suggestions gratefully received.

  • Comment on Is there a more elegant existing solution than @CARP_NOT

Replies are listed 'Best First'.
Re: Is there a more elegant existing solution than @CARP_NOT
by adrianh (Chancellor) on May 03, 2004 at 00:10 UTC
    As I want to report errors from the perspective of the user, I'm using Carp, and setting @Foo::Bar::Error::CARP_NOT to the complete list of modules under, and including Foo::Bar.

    Although I've not used it myself this looks like what Carp::Clan is meant to do.

Re: Is there a more elegant existing solution than @CARP_NOT
by Anomynous Monk (Scribe) on May 02, 2004 at 23:34 UTC
    Assuming your modules all use one another and will be loaded at compile time, something like:
    INIT { @CARP_NOT = map /::$/ && "Foo::Bar::$_", keys %Foo::Bar:: }
    or just have all the @CARP_NOT's aliased to one main one at at the top of each module, push the modules name onto it

    or have a coderef in @INC that detects your modules and adds to @CARP_NOT

Re: Is there a more elegant existing solution than @CARP_NOT
by Anonymous Monk on May 03, 2004 at 10:49 UTC
    Thanks for the feedback.

    As well as the solutions mentioned, I've just realized it's probably as easy as defining import in Foo::Bar::Error to be something like:

    { my %SEEN; our @CARP_NOT; sub import { my $caller = caller; return if $SEEN{$caller}; __PACKAGE__->export_to_level(1, @_); push @CARP_NOT, $caller; } }

    That seems to work (passes all my tests anyway!) - if not, I've now got some useful alternatives.

    Again, thanks for the advice.