"My half-life with Perl" from OSCON 2013 live encore performance

I've been asked by a couple of Perl groups to give a virtual presentation. Writing new material that would only have been shown once is a lot of work for a small reward.

But, I just happened to be cleaning out my virtual junk drawer, and stumbled across my "half my life with Perl" slide deck that I had presented at OSCON 2013. Most of the stuff is timeless, as it describes Perl's first 25 years, and my second 25 years and how I influenced Perl, and Perl influenced me, and how my company (Stonehenge) was changed by all of this, and in some ways even changed all of this as well.

chat2.pl just got real

20 years ago, I really wanted the chat2.pl domain name, to commemorate the one piece of code I ever contributed to the core. I even wrote the .pl administrators, and got no response.

Well, guess what I have now! chat2.pl!

Behold the wonder that is:

# XXX hardwired $PF_INET, $SOCK_STREAM, 'tcp'

# but who the heck would change these anyway? (:-)

$pf_inet = 2;

$sock_stream = 1;

$tcp_proto = 6;

Why, SystemV, and later Linux, didn't follow BSD numbers, I'll never know, …

Found a bug in File::Finder

I uploaded File::Finder to the CPAN more than a decade ago. I was using it for a project today, and found a bug that has been in there in the beginning. I forgot to localize $_ in ->contains, which clobbered File::Find's $_, used by just about everything else.

I couldn't even remember where I had put the git repo for the distro source, and once I found that, I couldn't remember how to build and test modules.

I'm getting old.

git blame across the entire codebase

A few years ago, a script showed up on the git mailing list that would effectively run "git blame" across the entire tree, and aggregate the line counts by author. Here's the first 50 authors as of commit 86714aaae213175ea8c716ad22c1e10300d5bf61:

Total lines: 2200186
  516667  23.48%  Jarkko Hietaniemi
  205425   9.34%  Karl Williamson
  200933   9.13%  Chris 'BinGOs' Williams
  145825   6.63%  Nicholas Clark
   86205   3.92%  Rafael Garcia-Suarez
   82823   3.76%  Gurusamy Sarathy
   57861   2.63%  Larry Wall
   53781   2.44%  Steve Peters
   49052   2.23%  Paul Marquess
   46528   2.11%  Perl 5 Porters
   45927   2.09%  Father Chrysostomos
   40271   1.83%  Sullivan Beck
   34158   1.55%  Steve Hay
   28840   1.31%  David Mitchell
   28330   1.29%  David Golden
   27898   1.27%  Ricardo Signes
   27055   1.23%  Nick Ing-Simmons
   25204   1.15%  Ilya Zakharevich
   23394   1.06%  Marcus Holland-Moritz
   18139   0.82%  Yves Orton
   16877   0.77%  Andy Dougherty
   16330   0.74%  Steffen Mueller
   16202   0.74%  Michael G. Schwern
   15076   0.69%  Zefram
   14224   0.65%  Brian Fraser
   13507   0.61%  Dave Mitchell
   13494   0.61%  Dan Kogai
   13257   0.60%  H.Merijn Brand
   10307   0.47%  Jerry D. Hedden
    9667   0.44%  Tels
    9443   0.43%  Jesse Vincent
    8610   0.39%  Andreas Koenig
    8266   0.38%  Craig A. Berry
    7453   0.34%  Abhijit Menon-Sen
    7328   0.33%  Hugo van der Sanden
    7051   0.32%  Vadim Konovalov
    7016   0.32%  Jim Cromie
    6946   0.32%  Tom Christiansen
    6648   0.30%  John E. Malmberg
    6305   0.29%  Shlomi Fish
    6276   0.29%  Abigail
    5917   0.27%  Radu Greab
    5877   0.27%  Yitzchak Scott-Thoennes
    5860   0.27%  Jos I. Boumans
    5558   0.25%  Marc Green
    5472   0.25%  Paul Fenwick
    5323   0.24%  Dave Rolsky
    5240   0.24%  Jan Dubois
    5138   0.23%  Andy Lester
    5089   0.23%  Tony Cook

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";