detecting "too heavy" views in Template Toolkit

$client is doing a lot of heavy lifting (perhaps accidentally) in some Catalyst-driven Template Toolkit code. Apparently, it's far too easy to pass a DBIx::Class object into the stash, and then trigger things that end up hitting the database... from the view. That wouldn't be horrible, except the same exact queries are being used in multiple places in the templates, causing many redundant identical queries to the database per page hit. (Note aside: if this was Rose::DB... I'd trivially jump to Rose::DB::Object::Cached. Problem solved.)

I wanted a way to see what method calls were being invoked on the objects in the stash. Simple... just subclass Template::Stash! Now I get a list of the component invoking the method, the path from the root stash to the object, and the method call being made.

package Test::Stash;
use base qw(Template::Stash);

use strict;
use warnings;
use Scalar::Util qw( blessed reftype );

use Template::Config;

our @PATH;
our $BYPASS = 0;

sub _dotop {
  my ($self, $root, $item, $args, $lvalue) = @_;

  unless ($BYPASS) {
    my $rootref = ref $root;
    my $atroot  = (blessed $root && $root->isa(ref $self));

    if ($atroot) {
      @PATH = $item;
    } else {
      push @PATH, $item;

    if (blessed $root && $root->can($item)) { # likely a method call
      if ($root =~ m{
                        # (redacted) $client top-level model class
                        Moose::Meta::Class:: .*?
                      )=}x) {
        ## ignore these
      } else {
        local $BYPASS = 1;
        my $component = $self->get(['component', 0, 'name', 0]);
        warn sprintf "%s: %s => %s\n",
          join('.', @PATH),
  return (shift @_)->SUPER::_dotop(@_);

# warn "Loaded Test::Stash... before is $Template::Config::STASH";

$Template::Config::STASH = __PACKAGE__;

# warn "Loaded Test::Stash... after is $Template::Config::STASH";


Mail::Audit and presuming a bit too much

I was tweaking my procmailrc today. My procmailrc recognizes a number of common pattern-based spam items and logs those into logs that I rotate on a regular basis. Anything else gets fed into a Mail::Audit-based "Sortmail" script. As I was testing a minor tweak, I noticed that the logfile for Sortmail (driven by the Mail::Audit object) wasn't getting any messages.

Long story short... I had opened the Mail::Audit logfile as "-", because I wanted it to use stdout, which in my procmailrc I had directed to the proper log.

But RJBS recently changed Mail::Audit from using the two-…

A compelling reason for Perl6

Had a great chat with the Thousand Oaks PerlMongers last night, as an ongoing series of conversations I've been having recently about finding a compelling reason for Perl6.

I was inspired by Larry's Onion talk to continue thinking about the relation of Perl5 and Perl6 (and frankly, me and Stonehenge as well).

First, Perl6 is not "the next Perl5". Perl5 will be alive and well for another decade at least, independently maintained and released. That's happening quite efficiently and effectively already. (Translated: "I will quite possibly be able to continue making money off Per…

comp.lang.perl.announce was stalled, now fixed

The NNTP injection host that I use to feed comp.lang.perl.announce had moved, and for some reason I had hardwired the old IP address into my posting script. Once I got that sorted out, it looks like it'll be business as usual for CLPA once again.

Perl to the rescue: case study of deleting a large directory

When I moved from OpenBSD to FreeBSD a year ago, I also had to move the email being handled by my server. As things were a bit different, I added a "Just-in-case" MailDir for one of my users so that no matter what else happened to the rest of their procmailrc, they'd have a backup copy.

Flash forward a year.

Yeah, you guessed it... we never turned that off. It's been accumulating spam at the rate of a few messages a second. For a year. I couldn't figure out why my 80GB of freespace a year ago was now dangerously under 15GB.

The MailDir/new directory was 2.5GB. Not t…