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

so i'm trying to subclass Business::OnlinePayment so that my apps can just call the new subclass. here's the ( broken ) constructor code:
package Unleashed::AuthorizeCard; use strict; use base qw/ Business::OnlinePayment /; sub new { my $class = shift; my $obj = bless( {}, $class ); my $realObj = $obj->SUPER::new( "AuthorizeNet" ); return $realObj; }
I thought that the call to $obj->SUPER::new() would pass the arg ... and it *sort of* does, because here's the error message:
[ proton ] :: perl -MUnleashed::AuthorizeCard -e '$foo = Unleashed::Au +thorizeCard->new();' unknown processor AuthorizeNet (syntax error at (eval 2) line 1, near +"use Unleashed::AuthorizeCard=" ) at -e line 1
i know that i could achive similar results with:
sub new { my $obj = Business::OnlinePayment->new( "AuthorizeNet" ); }
but i thought ( mistakenly? ) that the call to SUPER would do the same thing .....

Replies are listed 'Best First'.
Re: subclass and overridden constructor
by simonm (Vicar) on Dec 03, 2003 at 21:09 UTC
    I think you want something like the below:
    sub new { my $class = shift; my $obj = $class->SUPER::new( "AuthorizeNet" ); # rebless or do whatever with $obj return $obj; }
      that barfs even more ....
      unknown processor AuthorizeNet (Can't locate Unleashed/AuthorizeCard/A +uthorizeNet.pm in @INC
      and i do have the right mods installed. the test script ( sans subclassing ) works.

      i'm going to have to dig around in Business::OnlinePayment's source, i guess.

        Ah, sure enough -- if you look at the source of OnlinePayment.pm you'll see that it's got a very specific approach to subclassing already implemented.

        It might be straightforward to make a package that was a subclass of a specific processor, such as Unleashed::AuthorizeCard::AuthorizeNet inheriting from both your Unleashed::AuthorizeCard and Business::OnlinePayment::AuthorizeNet.

        If you want to dynamically handle whichever processor the end-user selects, you'll probably have to either generate subclasses on the fly, or use delegation rather than inheritance.

        (More generally, this illustrates one of the advantages of well-factored frameworks that use delegation internally; for example, I can imagine a version of Business::OnlinePayment that was divided into separate Transaction and Processor classes, which would allow you to subclass Transaction without worrying which Processor it was connecting to.)