in reply to Re: Prototypes allow overloading subs?
in thread Prototypes allow overloading subs?

rinceWind wrote:

It would be helpful if you could give an example of an application or a pattern where such a technique of distinct routines to handle different arglists would be useful.

Curiosly, I'm working with a similar issue, so here's an example. Let's say I want to create a 'people' object and save it in the database.

my $person = People ->new ->first_name( 'Tommy' ) ->last_name( 'Atkins' ) ->email( '' ) ->save; my $id = $person->get_id;

The above works if all mutators return the object (typically $self) instead of true.

Now let's say that later on I want resurrect poor Tommy Atkins from his database internment. Assuming I have his $id, I can do this:

my $person = People->new( $id ); print $person->first_name, ' ', $person->last_name;

In the first case we call the constructor with no argument and set all of the data by hand. In the second case we call the constructor with an ID and get what we need. This is method overloading (though I realize we're talking about function overloading, I think the point is the same). In many OO languages, you would code entirely different methods. Let's consider Java (I'm leaving a lot of stuff out here):

class People { // Java constructors have the same name as the class // People person = new People(); // People person = new People(id); public People() { // initialize empty object } public People( int id ) { // we can now access an object by id } }

The line public People( int id ) is called the method signature. By allowing the code to dispatch to different methods based upon different signatures, you simplify the logic tremendously. For Perl, without using an external module to fake it, you wind up with something like this:

sub new { my ($class,$id) = @_; my %data; %data = $class->_initialize($id) if $id; bless \%data, $class; }

That isn't too complicated, but many people will stick all of the logic in one method or try to do method dispatch based on the number and type of arguments. Further, the more argument types you have to deal with, the more complex this becomes. By forcing the programmer to use extra logic, you increase the chance for bugs. Method overloading on signatures reduces the amount of logic necessary and therefore reduces the amount of bugs and makes the code simpler.

As a side note, I generally prefere explicit 'get' and 'set' methods rather than overloading those methods. It makes the code easier to understand and doesn't confuse the programmer when they try to do something they shouldn't be able to do.

# no! If this is mapping to a database, you probably don't # want them to be able to change the id $person->id( $id );

With the above, it may silently fail. Instead, when the programmer tries to call set_id, they'll likely get a useful error message letting them know that this method is not available.


New address of my CGI Course.
Silence is Evil (feel free to copy and distribute widely - note copyright text)

Replies are listed 'Best First'.
Re: Re: Re: Prototypes allow overloading subs?
by Arrowhead (Monk) on Dec 05, 2002 at 14:49 UTC
    In my opinion the perceived "need" for this feature comes from too much attachment to the perfectly ordinary method name "new". Once you realize that not all factory/constructor methods have to be called "new", things become much clearer.
    my $person = People->new()->etc... ... my $himagain = People->restore($id);
    Other useful constructor names can be "new_from_file", "new_named", etc. That way, particularly when the arguments are called $a, $b, $c, you'll have documented what the (sometimes quite substantial) differences are between all the overloaded "new" methods.