Last week, I finally released the long-ago-announced new versions of Email::Send and Email::MIME, which together greatly reduce the memory used to store an email (and, in effect, to do many other things with PEP). There was one glitch that required a small tweak to Email::MIME's part-inflating code, but for the most part it went quite well. The only other non-bogus error reports I got were from people who relied on private Email::Simple code, or used code that did so.
For example, Email::LocalDelivery::Mbox needs to escape lines in the body that begin with "From ". To do this, it parsed the message into a header and body, and then returned the header followed by the escaped body. That sounds fine, except it did it like this:
# breaking encapsulation is evil, but this routine is tricky my ($head, $body) = Email::Simple::_split_head_from_body($$mail_r); $body =~ s/^(From\s)/>$1/gm;
It couldn't just create an Email::Simple to do that, because there was no
Email::Simple method to stringify just the headers -- except for
_headers_as_string
, which was private. (Of course, that didn't stop older
versions of Email::MIME from using it.) Instead, it relied on a different
method (well, subroutine) for doing something similar.
The clincher here is the comment! I don't really know what it means: the routine is tricky? If it does something that is tricky, and that is useful enough to use elsewhere, why isn't it just made public so nobody needs to break encapsulation? After all, both modules had the same author!
PEP has a lot of interface problems. Sometimes, fixing them is an enjoyable challenge. Other times, it's just annoying tedium.
Still, I think that a lot of the core ideas, and certainly the central goal of being as simple as possible, are good ones. What I'm most afraid of (and slightly exhilarated by) is the likelihood that I'll need to write new modules that replace the interface of a number of modules. Email::Send has some problems that, I fear, cannot be easily fixed without significant backcompat problems. Email::LocalDelivery, Email::Folder, and Email::Delete have interfaces so minimal (and in the case of Email::Delete, so unusual) that they seem difficult to reconcile into a set of tools that really seem designed to work together. Still, more modules will mean that even under Email:: there will be multiple choices for any single task, which hurts the value of the presently (mostly) one-module-per-task namespace.
I'll probably mumble about some of these plans on the PEP mailing list.
Re:So ask the damned author already
rjbs on 2007-02-21T15:01:43
Sure, but if it's difficult to build on a base class's public interface, the preferable solution is either to build your own support structure or extend the foundation provided by the public interface, not to drive pylons through the other guy's ceiling.
It's silly to say this is just a question of features versus simplicity. It's just about encapsulation: if the feature wasn't provided publicly, it should not have been used. It should have been reimplemented or placed in a public place.
The existing code didn't choose simplicity over functionality. It used the functionality through back channels.