Perl is a wonderful language for it allows one to accomplish certain task in many ways imaginable. One other distinct feature of Perl is it's 'implementation' of the OOP paradigm. In my short career I have seen code where it was heavily abused, and as well rare few snippets where it made the most perfect sense.

Just recently, I was working on an older piece of code that I wrote some months ago. The reason I had to go back and look at the code was due to a just sprang bug that I had to fix. Although I could have taken significantly less time to repair the script, it took me much longer this time due to poor OO design of some of my objects which impaired my ability to fully discern program logic and consiquently fix the bug in the most efficient way (minimal required code change/impact). Here, I'll attempt to describe the nature of this OO design flaw on an imaginary script...


imagine class Gadget.
package Gadget; # # 'build' new gadget... # return undef on fail. # sub new { my ($proto, $name, %args) = @_; my $self = bless {}, $proto; $self->{name} = $name; . . . work with %args . . . return $self; } # # check if a gadget has already been built. # sub is_built { my ($self, $name) = @_; return exists %_built_gadgets{$name}; } 1; package main; my $g1 = new Gadget('knob'); . . . create a bunch of other gadgets . . . if ($g1->is_built($athing_name)) { print "Gadget '$athing_name' has already been built!!\n"; } else { . . . do something useful here . . . }
Here the use and purpose of is_built() method is obscured by two factors. On the one hand, it seems that is_built() has something to do with the instance of a Gadget class (the $g1 object). Am I checking here whether object $g1 was built with name $athing_name? Or, do I simply check that an instance of class Gadget named $athing_name exists and that also it is somehow related to the $g1 object? On the other hand, there's this 'Gadget ... has already been built!' comment that gets printed on the success of the is_built() which sort of points me in the direction of thinking that the latter assertion is true (gadget named so-and-so exists).

Clearly, I had to change the way I used is_built() method in my code.

My immediate suggestion for improvement was to treat is_built() as a class method instead of as an per-object method. The problem is Perl is in no way as strict as C/C++ when it comes to these matters. Despite of this, I at times find myself frustrated over a piece of code that doesn't quite conform to common standards (logic). In this particular script, the
if ($g1->is_built($athing_name)) {
should be instead written as
if (Gadget->is_built($athing_name)) {
And also the is_built() sub has to be modified to this:
sub is_built { my ($class, $name) = @_; # return if dealing with a reference... # note: not tested ;) return if (ref $class eq '__PACKAGE__'); . . . # do stuff if this sub is called ast a class # method. ... }
since as far as the purpose and design of the imagined class goes, this method has no buisiness inside an object. When is used as a per-object method, it implies a weak (or confusing) logical statement. Frankly, I find it hard to frame original line in a clear statement of logic.

UPDATE: thanks Fletch for your comment, i fixed is_built() now (I forgot to update the post since I added a similar change to my script.. as i did in fact broke my script with the first implementation of is_built() :).

"There is no system but GNU, and Linux is one of its kernels." -- Confession of Faith

In reply to poor Perl OO design hinders maintenance effectiveness.. by vladb

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.