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

I have the following package
use strict; use warnings; package RemoteException; use Error; use base qw(Error); use overload ('""' => 'stringify'); sub new { my $self = shift; my $text = "" . shift; my @args = (); local $Error::Depth = $Error::Depth + 1; local $Error::Debug = 1; # Enables storing of stacktrace $self->SUPER::new(-text => $text, @args); } 1; package WineException; use base qw(RemoteException); sub h{ print "heheh\n"; } 1; package DeployException; use base qw(RemoteException); sub h{ print "heheh\n"; } 1; package BeerException; use base qw(RemoteException); sub h{ print "heheh\n"; } 1;
Now, my invocation script recognises RemoteException and DeployException, but not WineException or BeerException. If I invoke BeerException with use, Perl comes back with "Cannot find BeerException.pm". Am I being incredibly dense here?

Replies are listed 'Best First'.
Re: packages within packages
by Corion (Patriarch) on Jan 23, 2009 at 11:36 UTC

    use Foo::Bar; will go looking for a file named Foo/Bar.pm in @INC, so you need to either split up your exceptions into separate files or to always use RemoteException;, if your file is called RemoteException.pm.

Re: packages within packages
by Joost (Canon) on Jan 23, 2009 at 11:38 UTC
Re: packages within packages
by Mak3r (Novice) on Jan 23, 2009 at 13:27 UTC
    My solution - which includes some "programming by accident" - is this:
  • Create a package call MRFException which inherits the base class. I can never use this base class because it screws up Error.pm in some way.
  • I then declare MRFException in the script with a use statement. This apparently brings the other packages into the code namespace (... or something ...) and allows the BLOCK used by the try statement to "see" the derived classes I use for exception handling.

    tldr; it's a little bit funky but it seems to work.

      and thanks for the clarifications. Made me think a little bit deeper.
Re: packages within packages
by Bloodnok (Vicar) on Jan 23, 2009 at 11:43 UTC
    2 questions:
    • What's the name of your .pm file, RemoteException.pm ?
    • When you say ...my invocation script recognises RemoteException..., what do you mean by that ?

    I have to admit to self-interest in the answer to this question, since it rather looks as though I'm attempting to achieve the same thing...

    Update:

    Just noticed the scoping of the strictures, you might want to move them into the RemoteException package/class and maybe even copy them into the subclasses, so that they do you some good:-)

    A user level that continues to overstate my experience :-))

      The strictures are pragmas and lexically scoped. The scope (BLOCK) in which they appear is file level, so they apply through all code from there to the rest of the file, if not countered somewhere with a no statement.

        Hi shmem, long time no speak.

        I take your point - which I assumed to be as you state, however, I recall encountering a situation whereby I used strictures at the top of a multi-package file but found that I also had to use strictures within each individual package in order to gain the substantial benefits therefrom - ever since I've always included strictures in every package.

        .oO(Maybe it's time to review the situation)

        A user level that continues to overstate my experience :-))
Re: packages within packages
by Mak3r (Novice) on Jan 23, 2009 at 12:59 UTC
    Maybe I've trying to over-think things here (or import concepts from other languages ...)I'm trying to implement this: http://www.perl.com/pub/a/2002/11/14/exception.html?page=2

    the script that uses the packages looks like this:

    use Error qw(:try); use RemoteException; try { somefunction(1); } catch DeployException with { my $ex = shift; print "wibble\n"; } catch RemoteException with { my $ex = shift; print "dibble\n"; } catch WineException with { my $ex =shift; print "chinup\n"; }; sub somefunction { my $h =shift; throw WineException("hello world") if $h==1; return; }
    So I'm trying to "bring" the DeployException, RemoteException and WineException into the same namespace? as the rest. Now it will not print "chinup"; rather stopping at the RemoteException clause.

    Apologies, I now realise that I'm actually asking a question about Error.pm, not the use statement. Is there another package which is slightly more usable?