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

Hi,

I'm about to embark on an oo development project in perl and require (no pun intended) a way of implementing an interface in a fool proof fashion with compile time enforcement on required virtual methods. After having read through some info on abstract classes and interfaces, I decided to go with Class::Virtually::Abstract because it seemed to best meet my needs. Incidentally, I'm not sure why but I suspect overriding bless and import is fundamentally evil.

Anyway, the following code compiles, but there are still a few missing pieces of the puzzle. Namely:

Any good practices or advice welcome,

Thanks.

#################################### package iface2; print "\n\n",__PACKAGE__,"\n\n"; use base qw(Class::Virtually::Abstract); __PACKAGE__->virtual_methods(qw(new iface2_method)); 1; __END__ #################################### package iface1; print "\n\n",__PACKAGE__,"\n\n"; use base qw(Class::Virtually::Abstract); __PACKAGE__->virtual_methods(qw(new iface1_method)); 1; __END__ #################################### package class; use base qw(iface1 iface2); # See what methods we're obligated to implement. my @must_implement = __PACKAGE__->virtual_methods; print "\n",__PACKAGE__," must implement @must_implement\n\n"; # Check to make sure this PACKAGE implemented everything my @missing = __PACKAGE__->missing_methods; die __PACKAGE__ . ' forgot to implement ' . join ', ', @missing if @mi +ssing; sub new { my ( $class ) = shift; my $self = {}; bless $self, $class; return $self; } sub iface1_method { my ( $self, $arg ) = @_; print"\nclass->iface1_method : called with $arg\n\n"; return $self; } sub iface2_method { my ( $self, $arg ) = @_; print"\nclass->iface2_method : called with $arg\n\n"; return $self; } #################################### # bootstrap #################################### #!/ms/dist/perl5/bin/perl5.8 use Data::Dumper; use class; my $c = new class; $c->iface1_method("passed in to 1"); $c->iface2_method("passed in to 2"); print "Dump of object: class:\n",Dumper $c; print "\nEND \n\n";

Replies are listed 'Best First'.
Re: How best to implement multiple interfaces in perl
by stvn (Monsignor) on May 30, 2007 at 18:40 UTC

    Hmm, sounds like you might want to check out Moose. You can get compile time checked "interfaces" by using roles. Here is a very simplistic example of roles, however, it demonstrates totally abstract roles (the Printable role which just requires a to_string method to be implemented by any class which consumes it) as well as partially abstract roles in which only some methods are required.

    In addition, Moose offers full fledged attributes (instance variables, member variables, whatever you want to call them) which are supported in roles as well. A fair amount of information can be found in the Moose::Cookbook and you can also check out the website which has links to 4 talks given on Moose which serve as excellent introductions.

    -stvn
Re: How best to implement multiple interfaces in perl (fools)
by tye (Sage) on May 30, 2007 at 16:33 UTC
    a way of implementing an interface in a fool proof fashion with compile time enforcement on required virtual methods

    Frankly that sounds like you should re-examine your requirements. Compile-time checking on including specific methods is likely to be nearly a joke in Perl, IMO, because in Perl an "interface" is simply the name of the method. Checking that you got the name of the method right seems a pretty hollow insurance policy and not something I'd call "fool-proof".

    I'd be more impressed with tests that verify more than just the names of the methods and would run those tests before checking code in rather than jump through hoops trying to test at compile time.

    - tye        

Re: How best to implement multiple interfaces in perl
by gurky (Initiate) on May 31, 2007 at 10:23 UTC
    I don't think you can get the virtual methods from both interfaces with this module.
    As far as I understand, Class::Virtual relies on accessor methods to implement static data members and does not try to 'merge' multiple parent class data. Which means, in case of multiple definition of the same data member you get whatever comes first in your class isa call path.

    What's your rationale for wanting a template constructor? This looks interesting to me, since in Perl you don't usually ask for an explicit genericity mechanism.
Re: How best to implement multiple interfaces in perl
by blazar (Canon) on May 30, 2007 at 21:03 UTC
    I'm about to embark on an oo development project in perl and require (no pun intended) a way of implementing an interface in a fool proof fashion

    You can't: as soon as you write foolproof code, along comes a better fool.

    (Paraphrased from a Sherm Pendley's quote from clpmisc - incidentally, he also adds: "But it's still worth making the attempt.")