Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

rjbs (4671)

  (email not shown publicly)
AOL IM: RicardoJBSignes (Add Buddy, Send Message)
Yahoo! ID: RicardoSignes (Add User, Send Message)

I'm a Perl coder living in Bethlehem, PA and working Philadelphia. I'm a philosopher and theologan by training, but I was shocked to learn upon my graduation that these skills don't have many associated careers. Now I write code.

Journal of rjbs (4671)

Tuesday February 20, 2007
09:25 PM

finally released: less piggish email code

[ #32455 ]

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.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
More | Login | Reply
Loading... please wait.
  • Interface design is always a trade-off between simplicity and functionality. For Email::Simple the key was simplicity, but that restricted the functionality of the public interface, which of course makes it harder to build on top of that interface. We could, of course, have had an Email::Base with a big public interface, and Email::Simple and Email::MIME built on top of that, but I was really trying to get away from complex inheritance relationships. You seem to be wanting both simplicity and functionality,
    • 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 d