Nigel I have been looking at the "decorator" model, and I would do it differently.
Instead of using inheritance, I would use AUTOLOAD to implement quasi-inheritance. The relation is "Emulates" rather than "ISA". Does your design model have to be language independent, or can we use perl specific stuff like AUTOLOAD? Attached is an example (factor.pl, bignum.pm, strnum.pm) of this quasi-inheritance. As an exercise and alternative to Math::BigInt, I wanted a quickly implementable representation for arbitrarily large positive integers. I knocked this up first as strnum (objects are digit strings), but wanted something more fast and juicy: bignum (objects are arrays of ints), which required more human programming effort. Having strnum available first meant that I could prototype all the methods needed for a bignum object, and code them one by one, while having a working application at all stages. This is called the evo methodology. bignum has an AUTOLOAD method which makes a strnum object, calls the corresponding method and unwraps the return value if this is an object reference. There are a few assumptions here, but it would be possible to do something more generic, particularly for methods which pass and return different object of different classes, but you get the idea. Coming back to your "decorator" model. I suggest implementing your debug class as follows. This is generic and can be used with any classes, and copes with arbitrarily complex arguments and return values. #------------------------------- # calling code (all you need to do for each class) package foo::Debug; use MethodTracer; @ISA = qw(MethodTracer); . . $fred = new foo:Debug(@blah); # was new foo(@blah) foo:Debug->debug(1) # Turn on debugging of foo objects #------------------------------- MethodTracer.pm # This is called via inheritance to construct an object # of class blah::blah::Debug. This assumes that the "real" # class is called blah::blah package MethodTracer; use Data::Dumper; sub new { my ($pkg) = @_; $pkg =~ /\:\:\w+$/; my $underly = $`; $underly::new(@_); # relies on constructor respecting package param } sub debug # get and set debug at a class level { my $pkg = shift; @_ ? (${$pkg}::_debug = shift) : ${$pkg}::_debug; } sub DESTROY { 1; # to stop AUTOLOAD being called } sub AUTOLOAD { my ($self,@args) = @_; my $method = $AUTOLOAD; $method =~ s/\:\:Debug//; my $pkg = ref $self; print "called $method. Parameters:",Dumper(@args) if ${$pkg}::_debug; if (wantarray) { my @rv = &$method(@_); print "Return from $method. List context, values:",Dumper(@rv) if ${$pkg}::_debug; @rv; } else my $rv = &$method(@_); print "Return from $method. Scalar context, returned:",Dumper($rv) if ${$pkg}::_debug; $rv; } } 1; #---------------------------------- I intend to go to tonight's meeting. C U There. Ivor. -----Original Message----- From: Nigel Wetters [mailto:[EMAIL PROTECTED]] Sent: 08 January 2002 17:12 To: [EMAIL PROTECTED] Subject: Patterns in Perl reminder Study group starts tomorrow. For details, see http://london.pm.org/pipermail/london.pm/2002-January/007171.html _________________________________________________________________ Chat with friends online, try MSN Messenger: http://messenger.msn.com ----------------------------------------------------------------------- The information contained in this e-mail is confidential and solely for the intended addressee(s). Unauthorised reproduction, disclosure, modification, and/or distribution of this email may be unlawful. If you have received this email in error, please notify the sender immediately and delete it from your system. The views expressed in this message do not necessarily reflect those of LIFFE (Holdings) Plc or any of its subsidiary companies. -----------------------------------------------------------------------
bignum.pm
Description: Binary data
factor.pl
Description: Binary data
strnum.pm
Description: Binary data