Recently, I was pointing out the difficulty with subclassing a particular module. The module appeared to be object-oriented and useful, but it lacked some functionality that I needed. The answer? Subclass it!
Um, no.
The module, Data::FormValidator, makes a mistake that I see all too frequently and that, frankly, I have been guilty of in the past. It appears to be object oriented, but it uses function calls internally, rather than method calls. While I pointed this out in the post I referred to, this problem seems common enough that I feel it deserves a root node.
sub foo { my ($self, $data) = @_; $self->{bar} = _some_function($data); }
That might look perfectly reasonable at first, but what happens if I need to subclass this method and I need _some_function()? I can no longer call _some_function() directly as my subclass will be in a different namespace. I can't do $self->_some_function() as I have now added $self as the first argument. Reimplementing _some_function() in my subclass means that I'm duplicating code or using it as a wrapper around an ugly construct like the following:
sub _some_function { my ( $self, $data ) = @_; return ParentClass::_some_function($data); }
Needless to say, the above eliminates many of the benefits of subclassing. The following code may illustrate the problem more clearly.
#!/usr/bin/perl -w use strict; use Data::Dumper; package Foo; sub new { my $class = shift; bless {}, $class; } sub foobared { my $self = shift; $self->{foo} = _test( 3 ); } sub _test { shift } package Bar; @Bar::ISA = 'Foo'; sub foobared { my $self = shift; $self->{foo} = $self->_test( 3 ); } package Main; my $o = Foo->new; $o->foobared; print $o->{foo},$/; my $o2 = Bar->new; $o2->foobared; print $o2->{foo};
That prints out something similar to the following:
3 Bar=HASH(0xa065cc8)
If you're going to use object oriented programming, use method calls. Don't use functions.
Cheers,
Ovid
Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.
In reply to $functions xor $methods by Ovid
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |