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

ok, i have a class called transaction which i initialise with a request string. my application will soon support more than one type of transaction, so what i'd like to do is keep this in the code:
$work = new Transaction($request)
but have the Transaction class return a sub class of Transaction. let's say TransactionA or TransactionB. now i assume i would do something like:
sub new { my($r) = @_; if (&test($r)) { return new TransactionA($r); } else { return new TransactionB($r); } }
although i suppose Transaction isn't really a superclass anymore. anyway i guess my question really boils down to, "what is a clean way of creating an object of differing types based on data passed to a constructor?"

Replies are listed 'Best First'.
Re (tilly) 1: oo perl - using the super-class
by tilly (Archbishop) on Oct 03, 2000 at 15:07 UTC
    Perl has a standard way of doing it already.

    Create your sub-classes TransactionA and TransactionB, put Transaction in @ISA for each. Have your Transaction constructor respect inheritance by using the two-argument form of bless. For instance:

    sub new { my $class = shift; my $self = {}; %$self = @_; # Whatever fits - this is just and example return bless($self, $class); }
    And now your end code will be able to say:
    my $trans = new TransactionA;
    and it will all work.

    For more take a look at this tutorial.

      hm, no, that's exactly what i don't want. i never want to have the main code say:
      $trans = new TransactionA
      i want to say
      $trans = new Transaction($request);
      and have $trans be an instance of TransactionA or TransactionB. i'm not up on oo terminology, but i think what i really want is a TransactionFactory class. again, i'm not sure but the above describes what i'm looking for. i'm just wondering if it's a good thing to look for or is there a better design to use?
        Your original code was fine. Just make sure that neither of your two specific types of transaction inherit from the generic transaction, or you're toast on the new routine!

        -- Randal L. Schwartz, Perl hacker

        Well you can do whatever you want with the two argument form of bless, but you will break inheritance.

        OTOH containment (ie making one property of an object be a member of a different class) is usually cleaner than inheritance anyways, but if you play this kind of game you really should document it to avoid potential grief for someone else.