I've been working in Perl OO for over a year and I've seen a number of different ways to handle objects. I'm not talking about ways to represent an object in memory (hash vs. parallel array vs. whatever else). I'm talking about the way one accesses the internals.

Most of us come from either C++ or Java, when it comes to OO. And, not unsurprisingly, we have brought our old habits with us. For example, having one or two accessors for every single attribute. How many of us have either seen or written code similar to:

sub name { return @_ ? $self->{name} : $self->{name} = $_[0]; }

What about doing a getName() and setName() pair? I'm sure everyone's done something like that before.

In addition, you have to have knowledge of the object's internals within the new() function, and every single class has to have a new() function. There are as many bless's as there are classes. And, almost every single one of them is functionally identical.

If it wasn't for the fact that we are talking about the object's internals, most of us would look at that kind of code, snort in disgust, and say "Why isn't that in a base class?!?" We are so used to having the internals done for us that we forget that this very thing is what OO is best suited for!

I'd like to propose another way of doing things. Some may recognize this from a post satchboost had made about 2 months ago. (I am satchboost reincarnated ... I moved and forgot the password. *blushes*) The important thing about this proposal isn't the implementation, because implementation is the last thing done when designing an object hierarchy. The important thing is the contract between that class and the rest of the world.

The class will do (at least) the following:

  1. define_attributes()
  2. new() - this will call initialize()
  3. initialize()
  4. get()
  5. set()
  6. exists()
Obviously, this is a minimal set, and one of the things I'm hoping to do is to generate discussion on what the contract between the basest class and the rest of the world should entail.

new() does the blessing, then calls initialize() to do any class-specific set-up. The base initialize() is written as such:

sub initialize { my $self = shift; return $self->set(@_); }

The attributes are made through calling define_attributes(). This can be called either from a class or an instance of the class. A define_attributes() call could look like:

Foo->define_attributes( attr1 => 'NUM', attr2 => 'HASH', attr3 => 'STRING', );

Thus, the data-types of the attributes is known by the class. set() can then validate the data-type of the value given (using ref or isa) and enforce data-type integrity. (Obviously, this may or may not be desired. That's one of the things to discuss!)

get() and set() are generic accessors. The idea is to be able to call either one in a scalar or list context, thus allowing multiple get()s or set()s in one call.

Now, many people will say that this is an contract with a lot of overhead, thus it will slow people down. Yes, they're right. However, I ask you - are you really using Perl OO for the execution speed or the ease of development?

So, I put this concept out to the PM community for discussion. I'd be very interested in hearing what the elders, like merlyn and tye, have to say about this idea.


In reply to Idea on a Base class API by dragonchild

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.