December 2011 Archives

Sending a simple email: the current "modern" way

Some of my scripts are still set in stone age when it comes to the practice of sending emails. They almost invariably use Mail::Sendmail, a module that has not been updated since 2003 (and why should it if it doesn't break, right?). So far there's no complaints. The usual incantation for sending email using this module is:

use Mail::Sendmail;
mail(From=>$rfc_from, Sender=>$env_sender, Subject=>$subject, 
     To=>$rcpt, Cc=>$other_rcpt,
     Message=>$body) or warn "Can't send mail: $Mail::Sendmail::error";

But today I need to switch transport to sendmail. Despite what the name might suggest, Mail::Sendmail uses SMTP for transport and there's no alternative transport. There's also no support for SMTP auth, which my SMTP server now requires even for access from localhost. From what I read and tried once or twice in the past, the current "best practice" or recommended way is to use Email::Sender. Here's the incantation for sending mail using sendmail:

use Email::Sender::Simple qw(sendmail);
use Email::Simple;
use Email::Sender::Transport::Sendmail qw();
use Try::Tiny;

my $email = Email::Simple->create(
    header=>[To=>$to, From=>$from,

try {
} catch {
    print "Can't send mail: $_";

Okay, quite a bit longer and everything is fancy objectsie. But I think I'm okay with this because, like DBI, the incantation above is quite flexible and "scalable":

  • It's easy to switch transport to SMTP (just change two lines).

  • It's easy to add SMTP authentication (just pass arguments to transport constructor).

  • It's easy and clear where to add custom email headers (whereas in Mail::Sendmail, some arguments are "magical"/processed, they do not correspond 1:1 to headers).

  • It's easy to construct multipart email (construct the appropriate $email object).

In addition:

  • Envelope sender and RFC822 From is clearly separated, forcing beginners to understand the concept.

So there you have it, sending an email in Perl the modern way. No longer apt for one-liners though.

Personal end-of-year report for 2011

2011 is my most productive year yet in my "CPAN career": 495 releases (compared to 119 in 2010 and 54 in 2009). So far I have 115 distributions listed under my account (compared to around 15-20 in 2010, around 10 in 2009, and 2 before that). It really never occured to me that I would release over a hundred modules to CPAN, but all of a sudden I did. Perhaps next goal should be 1000 :)

Dist::Zilla helps a lot. I can't imagine doing manual tar and updating version numbers and README and a…

Module comparison wishlist #1

A while ago I did some comparison on serialization and logging modules, and I hope to do or see comparison on others. Here are some of them:

  • PID files. About a decade ago I wrote Proc::PID_File, including fork() handling, it does the job pretty well but I ended up abandoning it in favor of Proc::PID::File because I don't have time to maintain it and I hated the name. Turns out that there are several other modules pertaining to PID files like Piddy, Pid::File::Flock, IPC::PidStat, even Unix::PID (which is not recommended). The comparison article should discuss what issues surround managing PID files and also mention other means to detect program instances, like locking DATA filehandle (forgot which module does this).

  • INI files. Tried several INI modules in the past, not satisfied with any of them. Used Config::IniFiles in the end, but recently wrote another implementation (unfinished). A comparison article could be helpful.

  • Command-line-argument processing. Have always used Getopt::Long, heavily used App::Options a few years ago, now settling with my own module. Recently there have been some new development efforts like MooseX::GetOpt, Moo::Getopt, and App::Rad.

Scalar-only Perl

Now that Perl's builtin functions can directly operate on hashrefs and arrayrefs (I'm already starting to dread having to write push @{$foo->{bar}} instead of just push $foo->{bar}, but I'll be stuck with 5.10 for at least a couple more years), it chuckles me a bit imagining a future where beginners only use and know about scalars, and not arrays/hashes. Where they just need to memorize $ as the variable prefix. And where % and @ are nowhere to be found in baby Perl.

Among the issues with this would include the many special variables like @_, @INC and %INC, %ENV, %SIG and so on. We can provide some abstraction like self or MooseX::Declare for @_. With Moose et al, we already don't need to muck with @ISA directly.

Another would be list assignment, but I don't think beginners use it much.

Wouldn't it be cute? Albeit a bit pointless maybe. I can do away with context in Perl, but for now I like being able to have $thing, @thing, and %thing at the same time. Or do I?

Reducing spam comments to your blog

Since I’ve never used MT before I signed up to, it’s only recently that I found that MT does have some spam settings, which unfortunately are not turned on or default to the most conservative value. Along with other settings, you can reduce the number of spam comments being posted/notified to you.

  1. You can increase spam detection aggressiveness (Preferences → Spam). By default this is set to 0 which allows many spams to pass through. I set this now to 5 which seems to be okay (so far only 2 spams after a couple of days).

  2. You can disallow anonymous comments (Preferences → Comments → Setup Registration) or at least require email verification. By default anonymous comments are turned on and email verification is not required.

  3. You can use CAPTCHA! (Preferences → Comments). By default this is off, and unfortunately when I tried to turn it on (either using MT’s own CAPTCHA or reCaptcha), no image is displayed and yet all comments got rejected with the message “Text entered is not correct”. I guess this is currently a bug.

About Steven Haryanto

user-pic A programmer (mostly Perl 5 nowadays).