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 ]

samtregar (2699)

  (email not shown publicly)

Journal of samtregar (2699)

Wednesday July 05, 2006
03:48 PM

Using Perltidy with Emacs

I noticed this on the CPAN radar today:

From the docs it sounds like it runs perltidy when you save your file. That doesn't sound terrible, but I like my solution better. I have bindings so I can run perltidy on-demand, either on the whole file or on a particular region. Check it:

(defun perltidy-region ()
    "Run perltidy on the current region."
      (shell-command-on-region (point) (mark) "perltidy -q" nil t)

(defun perltidy-all ()
    "Run perltidy on the current region."
    (let ((p (point)))
        (shell-command-on-region (point-min) (point-max) "perltidy -q" nil t)
      (goto-char p)

(global-set-key "\M-t" `perltidy-region)
(global-set-key "\M-T" `perltidy-all)


Monday April 10, 2006
11:09 PM

Procmail has a strange way of saying "file not found"

When I'm faced with a bizarre error message the first thing I do is search for it on the web. Chances are I'm not the first one to see it and someone else has probably already taken the time to explain it. That didn't work today with this one, offered up by procmail as an excuse for not running SpamAssassin:

/home/stregar/bin/spamc: Transport endpoint is not connected
procmail: Program failure (126) of "/home/stregar/bin/spamc"

That's coming from a call to SpamAssassin's spamc client program, but the same error happened with any pipe call in my .procmailrc. I spent a long time distracted by the "Transport endpoint" business. It just sounds so authoritative and networky. But as far as I could tell the network was completely normal.

Finally I turned to the next line with it's enigmatic magic number 126. Turns out that's a return code from the shell call to run the pipe. And 126 is bash for "file not found." It all came together when I realized that $HOME on the mail-recieving host was no longer /home/stregar! As soon as I switched to using $HOME instead of hard-coding the path everything started working.

So, google, if you would be so kind, please index this report so that others may not have to stumble around for quite so long.


Tuesday April 04, 2006
06:18 PM

DateTime->now() versus localtime()

What's wrong with this picture:

   $ perl -MDateTime -e 'print DateTime->now()'

   $ perl -e 'print scalar localtime'
   Tue Apr  4 19:09:10 2006

It seems that DateTime->now() doesn't do what I thought it did. I thought it returned the current date and time at this point on the planet. What it actually does is return the current date and time in UTC! (And please don't tell me that DateTime can't reliably figure out my timezone. Perl's localtime() manages just fine!) (You can, however, lambaste me for not reading the DateTime docs, since it's quite clear that now() doesn't return local time.)

Unfortunately I discovered this only in the late stages of testing version 3 of a large application that makes moderately extensive use of Datetime. That means the "easy" way to fix this, namely:

    $ perl -MDateTime -e 'print DateTime->now(time_zone => "local")'

Isn't so easy, as it would mean touching a lot of files.

As far as I can tell I don't have a lot of good options here. I'm going to make a sub-class of DateTime which defaults to "local" for now(), new() and from_epoch(), but that will still mean touching lots of files. I did find discussion of this problem on the DateTime lists, but I don't think a solution made it into the module.

I did discover that Tim Bunce considers my chosen solution "trivial", whatever that means!


Thursday March 23, 2006
05:39 PM

Why your code might break on Fedora Core 5

I'm sure there are other reasons, but this one struck me as rather aggregious:

   $ export FOO=bar
   $ echo $FOO
   $ sudo bash -c 'echo $FOO'


That's right, sudo no longer passes through environment variables by default. I don't know about you, but this seems quite likely to bite lots of code I write. I often do environment setup (PERL5LIB, PATH, directory roots, etc) and then run a sub-process as another user via sudo. I'm expecting a flood of reports of problems from DBD::Oracle users as they find that ORA_HOME mysteriously stopped working when the upgrade to FC5.

The fix is easy, just undo the change discussed here:

I like Josh Bresser's comment about this change:

as long as there is a release note about it, it will only surprise the people who don't read the release notes

I guess that's true. Only problem is, it wasn't put in the release notes!


PS: Shout out to Michael Peters for tracking this one down.

Saturday December 03, 2005
05:35 PM

Putting MIME::Lite on a diet

There's nothing quite like some justified optimization to get the heart pumping. I've been working on a system which needs to produce multipart MIME messages very quickly. It's using MIME::Lite, which, it turns out, isn't actually all that lite. After solving the other bottlenecks in my code I was left with around 30% of my processing time locked-up in MIME::Lite's code.

My first stop was MIME::Fast. It certainly is fast, but unfortunately it also has some large memory leaks. Running at full speed it was losing around 5MB per second! I spent a few hours confirming that the leaks are somewhere in the huge XS codebase of MIME::Fast and not in the underlying gmime library. I gave up and filed a bug with the author.

That left me back with MIME::Lite, so I decided to see if I could speed it up. After a few hours of work I've come up with a patch which offers a 50% speedup for my use-case (creating two-part messages from parts in memory). For the curious, here's my work-log:

  • Starting work => MIME::Lite is building messages at 750/s
  • Use direct hash access for Attrs => 900/s
  • Change how Attrs are stored, moved sub-attrs into a separate structure. This avoids the {''} access for the vastly more common case of attribs without sub-attribs. => 980/s
  • Did some work optimizing fields() which is a hot method. => 1046/s
  • Tightened-up fields_as_string a bit. Might be worth making the pretty-printing optional if the spec doesn't require it. => 1057/s
  • Started testing with more realistic part sizes, new base => 910/s
  • inlined the popular routine known_types() => 930/s
  • Played with speeding up IO_* to little effect. Removing the wrap() indirection entirely would no-doubt help but it's a big project.

I sent the patch to the MIME::Lite maintainer, so hopefully this code will be available to all someday soon.


Tuesday August 30, 2005
12:39 PM

AJAX comes to HTML::PopupTreeSelect

I released HTML::PopupTreeSelect::Dynamic yesterday, a dynamic AJAXified version of HTML::PopupTreeSelect. Instead of sending the entire tree to the client when the page loads, the new dynamic version renders the tree on-demand, retrieving nodes via AJAX requests. The result is a widget that can browse arbitrarily large trees without imposing long initial page-load times.

This was a learning experience for me - I'd never used the Prototype library before. Now I'm wishing I'd encountered it earlier - it would have made a number of Javascript-intensive projects much easier. I also got a chance to play with HTML::Prototype, which makes using the Prototype library from Perl a breeze.

All this learning will hopefully help me in the near future. I'm planning a much more involved DHTML/AJAX application as part of the continued development of Arcos at Plus Three.


Sunday August 07, 2005
05:40 PM

It's all about the names

Working on MKDoc can be hard. It's a great system in many ways but every so often I get completely lost. I'm starting to think that fundamentally it's a naming problem. For example, consider the word "editor." MKDoc uses "editor" to mean four different things:

  1. The table which holds all users is called Editor.
  2. A user is considered an "editor" if they have editing rights to at least one document.
  3. The code that controls the part of the UI where users edit content is called an "editor." The base class is flo::Component but all the sub-classes live in flo/editor.
  4. The code that allows a document to be loaded and saved to the database lives in flo::Editor. This one is the hardest to characterize - it's probably implementing a design-pattern I don't know. Maybe the "editor" pattern? God, I hope so.

All this means that when you see a variables called $editor in MKDoc you really have no idea what you're dealing with. It could be a user, a specific type of user, a UI editor or an abstract encapsulation of the act of editing a document. That's hard.

So please, people, get your names right from the start. And if you can't get them right at least be consistent and careful. Having even two things named the same is bad. Having four is like declaring war on maintainance programmers.


Sunday June 05, 2005
11:16 PM

Progress on CGI::Application::Plugin::DBIProfiler

I've made some progress on a new module this weekend - CGI::Application::Plugin::DBIProfiler. Check it out:

That's the screen that pops up when you access a runmode of a CGI::App using the module. It shows profiling data for all DBI usage triggered by the request.

Of course, if it was done I'd be releasing it. I need to figure out why I'm getting bogus statement-less profile nodes (might be the fault of my test app rather than DBI::Profile). I also need to test it with a persistent DB handle between requests. I think I might need to make a patch to DBI::ProfileDumper to get that working right.

I'll also need to wait for CGI::Application v4.0 to release the module since it uses the new callback interface.


Thursday June 02, 2005
10:12 AM

Data::Phrasebook::Loader::ApacheFormat v1.00 Released

A few days ago I released the first version of Data::Phrasebook::Loader::ApacheFormat. If it's not completely obvious, this module will let you use phrasebooks in Config::ApacheFormat syntax.

I'm in the design stages for another module which will leverage this one - basically a CPAN version of the Krang::Message user-alerting system. More on that later.


Wednesday June 01, 2005
07:04 PM

Let's work together

We're looking for an elite Perl coder in New York to join our team at Plus Three. Check it out:

Speaking personally, I highly recommend you apply for this job immediately if you live in New York, love coding in Perl and would like to see the Democrats regain control of America. I've been loving my time at Plus Three and I'm sure you will too.