Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Shlomi Fish (918)

Shlomi Fish
  shlomif@iglu.org.il
http://www.shlomifish.org/
AOL IM: ShlomiFish (Add Buddy, Send Message)
Yahoo! ID: shlomif2 (Add User, Send Message)
Jabber: ShlomiFish@jabber.org

I'm a hacker of Perl, C, Shell, and occasionally other languages. Perl is my favourite language by far. I'm a member of the Israeli Perl Mongers, and contribute to and advocate open-source technologies. Technorati Profile [technorati.com]

Journal of Shlomi Fish (918)

Monday March 17, 2008
04:14 PM

Has-a as Is-a

[ #35922 ]

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

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.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.