<?xml version="1.0"?>
<!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN" "http://my.netscape.com/publish/formats/rss-0.91.dtd">

<rss version="0.91">
  <channel>
    <title>Random notes   </title>
    <link>/blog</link>
    <description>A pile of assorted scribblings, snippets and ramblings (mostly about programming and the software that makes my life easier).</description>
    <language>en</language>

  <item>
    <title>Climate variability and climate change: some semantics</title>
    <link>/blog/2009/03/11#some_definitions</link>
    <description>&lt;p&gt;&lt;a href=&quot;http://scienceblogs.com/highlyallochthonous/2009/03/a_few_semantics_about_climate.php&quot;&gt;This page&lt;/a&gt;
shows how variability and change differ using a couple of simple graphs.&lt;/p&gt;
</description>
  </item>

  <item>
    <title>Magic SysRq</title>
    <link>/blog/2008/11/13#magic-sysrq</link>
    <description>&lt;p&gt;Marc from our hosting provider pointed me to /proc/sysrq-trigger. Useful if
something&amp;#8217;s wedged, and you can&amp;#8217;t get a box to reboot in the normal way.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://aplawrence.com/Words2005/2005_04_13.html&quot;&gt;This page&lt;/a&gt; has more details,
as it doesn&amp;#8217;t seem to be documented in a normal man page.&lt;/p&gt;

&lt;p&gt;The capabilities should be documented in &amp;#8220;man proc&amp;#8221;, but (at least on my
system) are not. The &amp;#8220;sysrq&amp;#8221; is mentioned, but not documented. You can find
documentation in /usr/src/linux-2.4.29/Documentation/sysrq.txt if you have
source installed. This is from that file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;'r'     - Turns off keyboard raw mode and sets it to XLATE.

'k'     - Secure Access Key (SAK) Kills all programs on the
          current virtual console. NOTE: See important comments
          below in SAK section.

'b'     - Will immediately reboot the system without syncing
          or unmounting your disks.

'o'     - Will shut your system off (if configured and supported).

's'     - Will attempt to sync all mounted filesystems.

'u'     - Will attempt to remount all mounted filesystems read-only.

'p'     - Will dump the current registers and flags to your console.

't'     - Will dump a list of current tasks and their information
          to your console.

'm'     - Will dump current memory info to your console.

'0'-'9' - Sets the console log level, controlling which kernel
          messages will be printed to your console. ('0', for
          example would make it so that only emergency messages
          like PANICs or OOPSes would make it to your console.)

'e'     - Send a SIGTERM to all processes, except for init.

'i'     - Send a SIGKILL to all processes, except for init.

'l'     - Send a SIGKILL to all processes, INCLUDING init.
          (Your system will be non-functional after this.)

'h'     - Will display help ( actually any other key than those
          listed above will display help. but 'h' is easy
          to remember :-)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The key is also self-documenting: doing Alt-Sysrq-h (or any other unrecognized
key) prints out a HELP message that briefly reminds you of the above functions.
If you find that holding three keys is difficult, you do have some other
choices. You can trigger it manually:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;echo t &amp;gt; /proc/sysrq-trigger
&lt;/code&gt;&lt;/pre&gt;
</description>
  </item>

  <item>
    <title>Devel::Declare, Method::Signatures, oh my</title>
    <link>/blog/2008/09/24#devel-declare</link>
    <description>&lt;p&gt;Actually, I got another inspiration from Method::Signatures, for use with
CGI::Application.&lt;/p&gt;

&lt;p&gt;But while implementing that, I decided to extract the hard Devel::Declare
bits, and make a macro installer.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s a re-implementation of Method::Signatures using my Devel::Declare::Macro:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; package Method::Signatures;
 use Devel::Declare::Macro;

 sub import {
  install_macro(
    into           =&amp;gt; scalar(caller),
    name           =&amp;gt; 'method',
    proto_parser   =&amp;gt; \&amp;amp;make_proto_unwrap,
    proto_injector =&amp;gt; \&amp;amp;inject_from_signature
  );
 }

 sub make_proto_unwrap {} # as before, except return \%signature
 sub inject_from_signature {} # as before
 1;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I&amp;#8217;m somewhat confident it could simplify the implementation of Sub::Curried
and MooseX::Method::Signatures as well.&lt;/p&gt;

&lt;p&gt;Basically it packages the synopsis of Devel::Declare. As such, I don&amp;#8217;t think I
should maintain it. Comments welcome.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  package Devel::Macro;

  sub import {
      my &amp;#036;class = shift;
      my &amp;#036;pkg = caller;
      no strict 'refs';
      *{&amp;#036;pkg.'::install_macro'} = \&amp;amp;install_macro;
  }

  # Stolen from Devel::Declare's t/method-no-semi.t
  use Devel::Declare ();
  use Scope::Guard;
  use Sub::Name;
  sub install_macro {
      my %args   = @_;
      # I don't really understand why we need to declare method
      # in the caller's namespace.
      {
          no strict 'refs';
          *{&amp;#036;args{into}.'::'.&amp;#036;args{name}}   = sub (&amp;amp;) {};
      }
      Devel::Declare-&amp;gt;setup_for(
          &amp;#036;args{into},
          { &amp;#036;args{name} =&amp;gt; {
              const =&amp;gt; mk_parser(
                  &amp;#036;args{proto_parser}||sub{''},
                  &amp;#036;args{proto_injector}||sub{join' ', @_},
                  &amp;#036;args{pre_install}||sub{},
                  )
              },
          },
      );

  }
  our (&amp;#036;Declarator, &amp;#036;Offset);

  sub skip_declarator {
      &amp;#036;Offset += Devel::Declare::toke_move_past_token(&amp;#036;Offset);
  }

  sub skipspace {
      &amp;#036;Offset += Devel::Declare::toke_skipspace(&amp;#036;Offset);
  }

  sub strip_name {
      skipspace;
      if (my &amp;#036;len = Devel::Declare::toke_scan_word(&amp;#036;Offset, 1)) {
          my &amp;#036;linestr = Devel::Declare::get_linestr();
          my &amp;#036;name = substr(&amp;#036;linestr, &amp;#036;Offset, &amp;#036;len);
          substr(&amp;#036;linestr, &amp;#036;Offset, &amp;#036;len) = '';
          Devel::Declare::set_linestr(&amp;#036;linestr);
          return &amp;#036;name;
      }
      return;
  }

  sub strip_proto {
      skipspace;

      my &amp;#036;linestr = Devel::Declare::get_linestr();
      if (substr(&amp;#036;linestr, &amp;#036;Offset, 1) eq '(') {
          my &amp;#036;length = Devel::Declare::toke_scan_str(&amp;#036;Offset);
          my &amp;#036;proto = Devel::Declare::get_lex_stuff();
          Devel::Declare::clear_lex_stuff();
          &amp;#036;linestr = Devel::Declare::get_linestr();
          substr(&amp;#036;linestr, &amp;#036;Offset, &amp;#036;length) = '';
          Devel::Declare::set_linestr(&amp;#036;linestr);
          return &amp;#036;proto;
      }
      return;
  }

  sub shadow {
      my &amp;#036;pack = Devel::Declare::get_curstash_name;
      Devel::Declare::shadow_sub(&quot;&amp;#036;{pack}::&amp;#036;{Declarator}&quot;, &amp;#036;_[0]);
  }

  sub inject_if_block {
      my &amp;#036;inject = shift;
      skipspace;
      my &amp;#036;linestr = Devel::Declare::get_linestr;
      if (substr(&amp;#036;linestr, &amp;#036;Offset, 1) eq '{') {
          substr(&amp;#036;linestr, &amp;#036;Offset+1, 0) = &amp;#036;inject;
          Devel::Declare::set_linestr(&amp;#036;linestr);
      }
  }

  sub scope_injector_call {
      return ' BEGIN { ' . __PACKAGE__ . '::inject_scope }; ';
  }

  sub mk_parser {
      my &amp;#036;proto_parser   = shift;
      my &amp;#036;proto_injector = shift;
      my &amp;#036;install_cb     = shift;

      return sub {
      local (&amp;#036;Declarator, &amp;#036;Offset) = @_;
      skip_declarator;
      my &amp;#036;name = strip_name;
      my &amp;#036;proto = strip_proto;
      my @decl = &amp;#036;proto_parser-&amp;gt;(&amp;#036;proto);
      my &amp;#036;inject = &amp;#036;proto_injector-&amp;gt;(@decl);
      if (defined &amp;#036;name) {
          &amp;#036;inject = scope_injector_call().&amp;#036;inject;
      }
      inject_if_block(&amp;#036;inject);
      if (defined &amp;#036;name) {
          &amp;#036;name = join('::', Devel::Declare::get_curstash_name(), &amp;#036;name)
            unless (&amp;#036;name =~ /::/);
      }
      shadow(sub (&amp;amp;) {
          no strict 'refs';
          my &amp;#036;code = shift;
          &amp;#036;install_cb-&amp;gt;(&amp;#036;name, &amp;#036;code, \@decl);
          # So caller() gets the subroutine name
          *{&amp;#036;name} = subname &amp;#036;name =&amp;gt; &amp;#036;code if defined &amp;#036;name;
      });
      };
  }

  sub inject_scope {
      &amp;#036;^H |= 0x120000;
      &amp;#036;^H{DD_METHODHANDLERS} = Scope::Guard-&amp;gt;new(sub {
          my &amp;#036;linestr = Devel::Declare::get_linestr;
          my &amp;#036;offset = Devel::Declare::get_linestr_offset;
          substr(&amp;#036;linestr, &amp;#036;offset, 0) = ';';
          Devel::Declare::set_linestr(&amp;#036;linestr);
      });
  }

  1;
&lt;/code&gt;&lt;/pre&gt;
</description>
  </item>

  <item>
    <title>Markdown sample text</title>
    <link>/blog/2008/04/26#markdown-reference</link>
    <description>&lt;p&gt;This all the example text from &lt;a href=&quot;http://daringfireball.net/projects/markdown/basics&quot;&gt;Markdown basics&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Paragraphs, Headers, Blockquotes&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;A First Level Header
====================

A Second Level Header
---------------------

Now is the time for all good men to come to
the aid of their country. This is just a
regular paragraph.

The quick brown fox jumped over the lazy
dog's back.

### Header 3

&amp;gt; This is a blockquote.
&amp;gt;
&amp;gt; This is the second paragraph in the blockquote.
&amp;gt;
&amp;gt; ## This is an H2 in a blockquote
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Phrase Emphasis&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;Some of these words *are emphasized*.
Some of these words _are emphasized also_.

Use two asterisks for **strong emphasis**.
Or, if you prefer, __use two underscores instead__.
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Lists&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;bulleted:

* Candy.
* Gum.
* Booze.

numbered:

1. Red
2. Green
3. Blue

multiline:

* A list item.

  With multiple paragraphs.

* Another item in the list.
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Links&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;This is an [example link](http://example.com/).

This is an [example link](http://example.com/ &quot;With a Title&quot;).

I get 10 times more traffic from [Google][1] than from
[Yahoo][2] or [MSN][3].

[1]: http://google.com/        &quot;Google&quot;
[2]: http://search.yahoo.com/  &quot;Yahoo Search&quot;
[3]: http://search.msn.com/    &quot;MSN Search&quot;

I start my morning with a cup of coffee and
[The New York Times][NY Times].

[ny times]: http://www.nytimes.com/
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Images&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;![alt text](/path/to/img.jpg &quot;Title&quot;)

![alt text][id]

[id]: /path/to/img.jpg &quot;Title&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Code&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;I strongly recommend against using any `&amp;lt;blink&amp;gt;` tags.

I wish SmartyPants used named entities like `&amp;amp;mdash;`
instead of decimal-encoded entites like `&amp;amp;#8212;`.

If you want your page to validate under XHTML 1.0 Strict,
you've got to put paragraph tags in your blockquotes:

     &amp;lt;blockquote&amp;gt;
         &amp;lt;p&amp;gt;For example.&amp;lt;/p&amp;gt;
     &amp;lt;/blockquote&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#8212; &lt;/p&gt;

&lt;h1&gt;A First Level Header&lt;/h1&gt;

&lt;h2&gt;A Second Level Header&lt;/h2&gt;

&lt;p&gt;Now is the time for all good men to come to
the aid of their country. This is just a
regular paragraph.&lt;/p&gt;

&lt;p&gt;The quick brown fox jumped over the lazy
dog&amp;#8217;s back.&lt;/p&gt;

&lt;h3&gt;Header 3&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;This is a blockquote.&lt;/p&gt;

&lt;p&gt;This is the second paragraph in the blockquote.&lt;/p&gt;

&lt;h2&gt;This is an H2 in a blockquote&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some of these words &lt;em&gt;are emphasized&lt;/em&gt;.
Some of these words &lt;em&gt;are emphasized also&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Use two asterisks for &lt;strong&gt;strong emphasis&lt;/strong&gt;.
Or, if you prefer, &lt;strong&gt;use two underscores instead&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;bulleted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Candy.&lt;/li&gt;
&lt;li&gt;Gum.&lt;/li&gt;
&lt;li&gt;Booze.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;numbered:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Red&lt;/li&gt;
&lt;li&gt;Green&lt;/li&gt;
&lt;li&gt;Blue&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;multiline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A list item.&lt;/p&gt;

&lt;p&gt;With multiple paragraphs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another item in the list.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is an &lt;a href=&quot;http://example.com/&quot;&gt;example link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is an &lt;a href=&quot;http://example.com/&quot; title=&quot;With a Title&quot;&gt;example link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I get 10 times more traffic from &lt;a href=&quot;http://google.com/&quot; title=&quot;Google&quot;&gt;Google&lt;/a&gt; than from
&lt;a href=&quot;http://search.yahoo.com/&quot; title=&quot;Yahoo Search&quot;&gt;Yahoo&lt;/a&gt; or &lt;a href=&quot;http://search.msn.com/&quot; title=&quot;MSN Search&quot;&gt;MSN&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I start my morning with a cup of coffee and
&lt;a href=&quot;http://www.nytimes.com/&quot;&gt;The New York Times&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/path/to/img.jpg&quot; alt=&quot;alt text&quot; title=&quot;Title&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/path/to/img.jpg&quot; alt=&quot;alt text&quot; title=&quot;Title&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I strongly recommend against using any &lt;code&gt;&amp;lt;blink&amp;gt;&lt;/code&gt; tags.&lt;/p&gt;

&lt;p&gt;I wish SmartyPants used named entities like &lt;code&gt;&amp;amp;mdash;&lt;/code&gt;
instead of decimal-encoded entites like &lt;code&gt;&amp;amp;#8212;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you want your page to validate under XHTML 1.0 Strict,
you&amp;#8217;ve got to put paragraph tags in your blockquotes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; &amp;lt;blockquote&amp;gt;
     &amp;lt;p&amp;gt;For example.&amp;lt;/p&amp;gt;
 &amp;lt;/blockquote&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
</description>
  </item>

  <item>
    <title>A couple of Vim links</title>
    <link>/blog/2007/12/17#vim-links</link>
    <description>&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://jmcpherson.org/editing.html&quot;&gt;Efficient Editing With vim - Jonathan McPherson&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.viemu.com/a-why-vi-vim.html&quot;&gt;Why, oh WHY, do those #?@! nutheads use vi?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.vim.org/tips/tip_search_results.php?keywords=&amp;amp;order_by=rating&amp;amp;direction=descending&amp;amp;search=search&quot;&gt;Search vim online tips by rating&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;Emacs is far too &lt;em&gt;small&lt;/em&gt; to be a proper kitchen sink &amp;#8212; &lt;a href=&quot;http://xach.livejournal.com/90933.html?thread=140853#t140853&quot;&gt;david feuer&lt;/a&gt;&lt;/p&gt;
</description>
  </item>

  <item>
    <title>Vim config, plugins</title>
    <link>/blog/2007/11/22#vim</link>
    <description>&lt;p&gt;My preferred editor is &lt;a href=&quot;http://www.vim.org/&quot;&gt;Vim&lt;/a&gt;. I use a couple of plugins that make it even
nicer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/files/ack.vim&quot;&gt;ack&lt;/a&gt; (&lt;a href=&quot;http://search.cpan.org/dists/App::Ack&quot;&gt;enhanced grep replacement&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.vim.org/scripts/script.php?script_id=159&quot;&gt;minibufexplorer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.vim.org/scripts/script.php?script_id=556&quot;&gt;perl-support&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.vim.org/scripts/script.php?script_id=517&quot;&gt;The Vim Outliner&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My &lt;a href=&quot;/files/.vimrc&quot;&gt;local vimrc&lt;/a&gt; has a couple of niceties too.&lt;/p&gt;
</description>
  </item>

  <item>
    <title>Markdown</title>
    <link>/blog/2007/11/22#markdown</link>
    <description>&lt;p&gt;&lt;a href=&quot;http://daringfireball.net/projects/markdown/&quot;&gt;Markdown&lt;/a&gt; is neat.&lt;/p&gt;
</description>
  </item>

  <item>
    <title>Some of my favorite applications</title>
    <link>/blog/2007/11/22#list</link>
    <description>&lt;p&gt;In no particular order, the following applications make my life so much easier:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;debian/ubuntu&lt;/li&gt;
&lt;li&gt;gaim&lt;/li&gt;
&lt;li&gt;galeon&lt;/li&gt;
&lt;li&gt;gnome&lt;/li&gt;
&lt;li&gt;liferea&lt;/li&gt;
&lt;li&gt;pan&lt;/li&gt;
&lt;li&gt;perl&lt;/li&gt;
&lt;li&gt;privoxy&lt;/li&gt;
&lt;li&gt;rhythmbox&lt;/li&gt;
&lt;li&gt;subversion&lt;/li&gt;
&lt;li&gt;thunderbird&lt;/li&gt;
&lt;li&gt;vim&lt;/li&gt;
&lt;/ul&gt;
</description>
  </item>

  <item>
    <title>Galeon + Privoxy = nice!</title>
    <link>/blog/2007/11/22#current</link>
    <description>&lt;p&gt;After getting increasingly annoyed with &lt;a href=&quot;http://www.mozilla.com/&quot;&gt;Firefox&lt;/a&gt; and its crazy memory 
leaks, I temporarily switched to &lt;a href=&quot;http://www.opera.com/&quot;&gt;Opera&lt;/a&gt;. After dealing with the ugly QT 
layout (by using the beautiful &amp;#8220;tango&amp;#8221; skin), it was mostly enjoyable. But 
some issues cropped up (horrible javascript performance mostly), so I went to 
look for another browser.&lt;/p&gt;

&lt;p&gt;I looked through Ubuntu&amp;#8217;s applications, and tried &lt;a href=&quot;http://galeon.sourceforge.net/&quot;&gt;Galeon&lt;/a&gt;, &lt;a href=&quot;http://www.gnome.org/projects/epiphany/&quot;&gt;Epiphany&lt;/a&gt; 
and &lt;a href=&quot;http://w3m.sourceforge.net/&quot;&gt;w3m&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;w3m is awesome, but for my &lt;a href=&quot;http://www.exposuremanager.com/&quot;&gt;work&lt;/a&gt; I really need a graphical browser with 
JavaScript support&lt;/li&gt;
&lt;li&gt;Epiphany seemed to lack features I felt I needed&lt;/li&gt;
&lt;li&gt;Galeon looked OK, and soon proved to be my favorite&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The biggest thing missing from all of them was AdBlock support. But after some 
googling, I found a lead to &lt;a href=&quot;http://www.privoxy.org/&quot;&gt;Privoxy&lt;/a&gt;. What a find! It&amp;#8217;s absolutely 
painless to install, and Gnome has a global http proxy setting, which makes 
Privoxy immediately useful for every browser I care to use. Brilliant!&lt;/p&gt;

&lt;p&gt;Life is good again :-)&lt;/p&gt;
</description>
  </item>

  <item>
    <title>Email::MIME::* modules aren&amp;#8217;t very close friends</title>
    <link>/blog/2007/04/11#attachment_stripper</link>
    <description>&lt;p&gt;The &lt;a href=&quot;http://emailproject.perl.org/&quot; title=&quot;The Perl Email Project&quot;&gt;&lt;code&gt;Email::*&lt;/code&gt;&lt;/a&gt; modules are all pretty neat, with a pleasant API. But 
combining them isn&amp;#8217;t always as effortless as you&amp;#8217;d expect.&lt;/p&gt;

&lt;p&gt;For my email2blog script, I use &lt;a href=&quot;http://search.cpan.org/dist/Email-Filter&quot;&gt;&lt;code&gt;Email::Filter&lt;/code&gt;&lt;/a&gt; as the bridge between the 
MTA and blosxom:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; # grab email from STDIN
 my &amp;#036;mail = Email::Filter-&amp;gt;new;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;&amp;#036;mail&lt;/code&gt; object has nifty methods that make it very simple to accept or 
reject a message.&lt;/p&gt;

&lt;p&gt;Once I accept a message, I take out the attachments with 
&lt;a href=&quot;http://search.cpan.org/dist/Email-MIME-Attachment-Stripper&quot;&gt;&lt;code&gt;Email::MIME::Attachment::Stripper&lt;/code&gt;&lt;/a&gt;. The first step is to construct a 
stripper based on the incoming email:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; # make stripper
 my &amp;#036;strip = Email::MIME::Attachment::Stripper-&amp;gt;new(
             Email::MIME-&amp;gt;new( &amp;#036;mail-&amp;gt;simple-&amp;gt;as_string ),
             force_filename =&amp;gt; 1
 );
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I&amp;#8217;m not impressed with the hoops I have to jump through there. It should be 
easy for &lt;code&gt;EMA::Stripper&lt;/code&gt; to build its own &lt;a href=&quot;http://search.cpan.org/dist/Email-MIME&quot;&gt;&lt;code&gt;Email::MIME&lt;/code&gt;&lt;/a&gt; object when 
handed an &lt;code&gt;Email::Simple&lt;/code&gt; object. But in fact, even &lt;code&gt;Email::MIME&lt;/code&gt; itself 
doesn&amp;#8217;t offer that option.&lt;/p&gt;

&lt;p&gt;Next up is taking apart the MIME email:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; # strip attachments
 my &amp;#036;msg = &amp;#036;strip-&amp;gt;message;
 my @attachments = &amp;#036;strip-&amp;gt;attachments;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&amp;#8217;s pretty straightforward. &lt;code&gt;&amp;#036;msg&lt;/code&gt; is an &lt;code&gt;Email::MIME&lt;/code&gt; object, without the 
attachments. To get at the plaintext body is still not very comfortable:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; # extract plaintext body
 my &amp;#036;text = first { &amp;#036;_-&amp;gt;content_type =~ m{text/plain} } &amp;#036;msg-&amp;gt;parts;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Maybe that&amp;#8217;s because there may not be a &lt;code&gt;text/plain&lt;/code&gt; part with meaningful 
content, but I wouldn&amp;#8217;t expect &lt;code&gt;&amp;#036;msg-&amp;gt;body&lt;/code&gt; to be empty after the strip 
operation. It is though, so that fancy grep is necessary.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;@attachments&lt;/code&gt; array on the other hand is very easy to work with. It has 
just the things you need, and nothing else.&lt;/p&gt;

&lt;p&gt;All in all, the script ended up being about 60 well-spaced lines long, with 
most of that being taken up by sanitizing the input. The fact that I didn&amp;#8217;t 
actually have to think how MIME encoding works under the hood was a big plus, 
and for that I&amp;#8217;m very happy with the &lt;a href=&quot;http://emailproject.perl.org/&quot; title=&quot;The Perl Email Project&quot;&gt;PEP Project&lt;/a&gt;.&lt;/p&gt;
</description>
  </item>

  </channel>
</rss>
