Subject: Has-a as Is-a

From: Shlomi Fish <[email-masked]>
Date: Wed, 27 Feb 2008 22:22:55 +0200

Recently I've encountered a modularity issue in my code, I had a function like 
the following

<<<<<<<<<<<<<<
sub _is_event_pass
{
	return ($self->_event->is_ok() ||
                $self->_event->is_skip() ||
                $self->_event->is_todo()
               );
}

As you can see all I'm doing is calling methods on the _event. The right thing 
to do would have been to move it as method to the class of the _event() that 
will then use the object's instance itself. Now the problem is that the 
_event() field can be any of the TAP::Result:: hierarchy of classes from 
here:

http://search.cpan.org/dist/Test-Harness/

And it wouldn't be a good idea to sub-class and re-bless all of them.

So what to do?

What I eventually did is create an EventWrapper class, that has a field which 
is the actual object. Then I'm delegating all the methods of the TAP::Result 
classes that I use to that field. I.e:

<<<<<<<<<<
sub is_ok
{
	my $self = shift;

	return $self->_tp_result()->is_ok();
}

sub is_todo
{
	my $self = shift;

	return $self->_tp_result()->is_todo();
}

(only I'm auto-generating these methods of-course).

And then I defined the is_pass function there like this:

<<<<<<<<<<<<
sub is_pass
{
	my $self = shift;

	return ($self->is_ok() || $self->is_todo() || $self->is_skip());
}

Which works because these methods are delegated.

So ::EventWrapper behaves like TAP::Result ("is-a") while actually only 
containing it ("has-a"). It's a useful technique.

Of course, I made a good use of the fact that Perl is dynamically-typed and 
evaluates methods at run-time. If I wanted to do the same in strongly-typed 
OO languages, then I would have needed to figure out a way to delegate to all 
the methods of the various different classes in the hiearachy. Perhaps using 
run-time classes.

Regards,

	Shlomi Fish

---------------------------------------------------------------------
Shlomi Fish      [email-masked]
Homepage:        http://www.shlomifish.org/

I'm not an actor - I just play one on T.V.