auto_inherit, inherit

Eric Wilhelm scratchcomputing at gmail.com
Wed Oct 3 21:47:16 BST 2007


# from Andy Armstrong
# on Wednesday 03 October 2007 12:17:

>Eric: auto_inherit, inherit. It allows you to chain a bunch of
>TAP::Harness subclasses so that each sees its predecessor (rather
>than TAP::Harness) as its superclass, right?
>
>So it allows me to install both of
>
>package Foo;
>our @ISA = qw( TAP::Harness );
>
>package Bar;
>our @ISA = qw( TAP::Harness );
>
>I load Foo and have it subclass T::H and then when I load Bar it
>becomes a subclass of Foo rather than TAP::Harness. Is that how it
>works?

Well,

  package Foo;
  use base 'TAP::Harness';
  use constant auto_inherit => 1;

  package Bar;
  use base 'TAP::Harness';
  use constant auto_inherit => 1;

But the Foo->inherit("TAP::Harness") and Bar->inherit("Foo") has to 
happen.  See App::Prove::require_harness().

>Shouldn't that mechanism be available more generally? In TAP::Base
>for example?

Maybe, but (as-implemented) it wouldn't work there.  Currently, 
App::Prove is keeping track of which one is on top of the stack.  I 
wouldn't want to apply this scheme to the entire TAP::* family without 
doing something more robust.

This was really meant only to be a simple way to layer specialized 
harnesses on top of each other.  As long as they all call SUPER::foo() 
for each overridden foo(), it's a valid mechanism.

>It feels to me as if it's attempting to be a delegation mechanism -
>shouldn't we just implement / use delegates?

Maybe.  Iff it could be done conveniently and without every delegate 
needing hooks in Harness.pm.  Delegation requires a hasa relationship, 
but it means the harness has to select what to delegate to and when to 
delegate to it.  What about having two delegates doing the same thing?  
How do they layer on top of each other?  Are they supposed to have 
methods chained or in sequence?

In other words, do you want to say that subclassing TAP::Harness is 
simply not the way to customize/specialize it?  Fine, but I think 
getting that API right will be difficult, it would have to be easy to 
understand or it raises the barrier to entry, and it seems like it 
would be awfully susceptible to an "ivory tower" issue.  I also think 
it might be limiting the flexibility.  If that's done only in the 
service of some presumed "safety", I would call that a net loss.

So, my take is that chained subclassing (at the Harness) is simple 
enough to handle simple cases simply and powerful enough to make 
complicated cases possible without needing a lot of support code or 
documentation.  The caveat is that order cannot matter and validation 
has to be left up to the base class (most subclasses will get that 
right without even trying.)  This is sort of a "enough rope to shoot 
yourself in the foot" method, but if I were scared of rope I wouldn't 
use perl.

--Eric
-- 
Atavism  n:  The recurrence of any peculiarity or disease of an ancestor
in a subsequent generation, usually due to genetic recombination.
---------------------------------------------------
    http://scratchcomputing.com
---------------------------------------------------


More information about the tapx-dev mailing list