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:
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
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |