Optional Subclass Loading Problem

Nik Clayton nik at ngo.org.uk
Tue Jul 4 02:53:51 PDT 2006


Tom Hukins wrote:
[...]
> This works fine until a subclass fails to compile due to the
> programmer (me) making a mistake while adding new code.  The "eval use
> ..." fails so it seems like methods have suddenly vanished.  If the
> method exists in the Thing superclass, the methods get called with
> incomplete functionality which confuses the poor programmer.
> 
> So, can anyone think of a good way I could distinguish between
> different types of failure I might encounter and an elegant way of
> dealing with them?  I want to ignore "subclass not found errors", as
> not all types of thing currently (or will ever) have their own
> subclass.  So far, the only other type of error I have encountered is
> a compilation error, but might I encounter others (eg. file unreadable
> due to permissions)?

It doesn't solve the problem you pose, but could you work around it by
having a test that does the equivalent of

     find . -name \*.pm | xargs perl -c

to make sure that all the .pm files compile correctly?  That way you
could be reasonably certain that if the eval fails it's because there
was a problem with the load.

Alternatively, create subclasses for everything, even if some of them
are no more than:

    package Thing::foo;

    use base qw(Thing);

    1;

Taking a look at "perldoc require" it's got Perl code that claims to be
equivalent to require in it, complete with calls to die().  It may be the
case that that code also shows all the ways in which require() might
fail, in which case you could use that.  That's still quite fragile though.

Ah, here's a thought.  You can check %INC after the use.  I've just done
a quick test.

=== t.pl ===
#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

use lib '.';

eval "use Works;";
eval "use Syntax;";
eval "use doesNotExist;";

print Dumper \%INC;
=== end ===

=== Works.pm ===
package Works;
1;
=== end ===

=== Syntax.pm ===
package Syntax;
sob { print "boo hoo\n"; }  # Syntax error on this line
1;
=== end ===

If you run t.pl you'll see that there are entries for Works.pm and
Syntax.pm, indicating that both of those were found (even though
Syntax.pm has a syntax error).

There's no entry for "doesNotExist.pm", indicating that the file
couldn't be found.

So workable logic is probably:

    eval "use $subclass";
    if($@) {
        # Rethrow the error if the module was found but couldn't
        # be compiled
        die $@ if exists $INC{$self->name() . 'pm'};
    }

N



More information about the MiltonKeynes-pm mailing list