hanenkamp has asked for the wisdom of the Perl Monks concerning the following question:

I am putting together an API for abstract document production. Essentially, each producer is an object with custom methods for producing a document.

Each document producing method may produce documents of a single MIME-Type or of varying MIME-Types depending on the arguments passed. I would like some way of knowing the MIME-Type of the document sometime before the document is produced. The goal is to make the process of fetching the MIME-Type easy to understand, but also making the job of the coders who write the producers as easy as possible in the process.

However, I'm not certain the best way to create the API, so I thought I'd present the question to the Perl Monks to see what suggestions others could make.

Here are some of the ideas for solving this problem. The content producer method will print its output to the currently selected filehandle unless the proposed solution passes one directly. The method foo is the document to be produced.

# Special Argument $mime_type = $producer->foo(undef, @args); $producer->foo($fh, @args); # Explicit Context # wantarray is false versus wantarray is undefined # When wantarray is false we return an object with a # mime_type method. $mime_type = $producer->foo(@args)->mime_type; $producer->foo(@args); # Implicit Context # wantarray is false versus wantarray is undefined # When wantarray is false we return the MIME-Type directly. $mime_type = $producer->foo(@args); $producer->foo(@args); # Callback # This would have to be augmented with the use of threads # to really work my $mime_type; $producer->foo(sub { $mime_type = $_[0] }, @args); # Special method $mime_type = $producer->foo_mime_type(@args); $producer->foo(@args); # Double-call (very bad idea, but it's a brainstorm) select $null_fh; $mime_type = $producer->foo(@args); select $real_fh; $producer->foo(@args); # Documents as objects $document = $producer->foo(@args); $mime_type = $document->mime_type; $document->render;

That's about all I can come up with. I think I'd probably most lean towards the last one as it seems that this problem is really a result of incorrectly making a produced document a method rather than an object. Yet, this may make the job of the coders of new producer objects more difficult. With the last design they now have to create objects that render documents rather than just render the document or return the MIME type. I can think of some ways to make this easier, but it still seems a little more complicated than I would prefer.

I would like to hear other ideas and hear suggestions from others as this is a pretty major part of my API and I want it to work well. Thanks.

Replies are listed 'Best First'.
Re: A question of design
by hanenkamp (Pilgrim) on Sep 26, 2003 at 15:06 UTC

    One more I just came up with:

    # MIME Type as first line of document # Document prints MIME type on first line of returned document # I need to create a special tied filehandle to do this select $special_fh; $producer->foo(@args);

    Seems counter-intuitive, though.

Re: A question of design
by iburrell (Chaplain) on Sep 27, 2003 at 00:25 UTC
    I would say that overloading one method to do two completely different is a bad idea regardless of how you call it.

    I think the final design makes the most sense. It separates the functionality for deciding which handler to use from writing out the object.

    Another way to handle it is store the state in the producer. Then have separate methods to fetch the mime_type and to write out the document.

    $producer->start(@args); my $type = $producer->mime_type(); $product->generate();