The goal is to have any module under CAD::Drawing::IO::* be able to act as a 
plugin regardless of whether it was installed before or after 
CAD::Drawing::IO.

In my latest setup, IO.pm has a BEGIN block which does a find() on each 
directory in @INC which contains a "CAD/Drawing/IO/".  Foreach module found 
there (the first by that name anyway,)  it then does a couple of checks to 
see how the module wants to be plugged-in:

    foreach my $mod (keys(%found)) {
        if(eval("require " . $mod)) {
            foreach my $action qw(load save) {
                my $type = eval('$' . $mod . '::can_' . $action . '_type');
                $type || next;
                $handlers{$action}{$type} = $mod . '::' . $action;
            }
            if(eval('$' . $mod . '::is_inherited')) {
                push(@ISA, $mod);
            }
        }
        else {
            $@ && warn("warning:\n$@ for $mod\n\n");
        }
    }

So, to be a load/save plugin, the IO::DWG module would contain the following:
our $can_save_type = "dwg";
our $can_load_type = $can_save_type;

and to be simply inherited into CAD::Drawing::IO, a module would just have:
our $is_inherited = 1;

Now, when IO.pm is trying to find which module to use.   It will call 
ModuleName::check_type($filename, $type) where $type may or may not be 
defined.  It then simply returns ModuleName::save($drawing, $args, \%opts) 
for the first package which claims to be able to save this type.

I looked at polymorphism and simply getting an object from each module, but 
this object would really just be a hook (like a blessed string) into that 
module's namespace and would prohibit all other plug-ins from using the 
$drawing object directly via inheritance.

Any thoughts?

Thanks,
Eric


Reply via email to