[Israel.pm] Has-a as Is-a

Shlomi Fish shlomif at iglu.org.il
Wed Feb 27 12:22:55 PST 2008

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() ||

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 


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.


	Shlomi Fish

Shlomi Fish      shlomif at iglu.org.il
Homepage:        http://www.shlomifish.org/

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

More information about the Perl mailing list