Enhanced Smoking Techniques for Saving My Ass

In which we learn how a series of cockups can reinforce lessons about money, and potentially provide some new infrastructure for Perl5 Core

The Background

If you were at YAPC::NA this past summer1, you may have attended my talk about the lessons I've learned from starting and running my company Tamarou. One of the points I emphasized in the talk was the importance of understanding the nature of money. What I wanted to convey is that "money" is not a finite substance (like we treat it when thinking about the stereotypical household budget), but rather a fluid (which is how people who work with money professionally -- accountants, financial advisors, stock brokers and other gamblers -- regard it). Anyone who has seen the talk may also have noticed that I was a little tired while delivering it2. That exhaustion was largely because I had forgotten this important point about the fluid nature of money myself, and was attempting to heroically unjam a project that had gotten firmly -- and in the end, fatally -- stuck.

I don't want to go into the details on what went wrong with the project, because at this point, they're inconsequential. The critical point is that our cashflows have been seriously impacted by the implosion of this project. In addition to the financial impact, it also wrecked me on an personal level for a couple months, until the recent Moving To Moose hackathon gave me an opportunity to get some distance and clarity on the situation3, and to appreciate and understand where we are now: Tamarou needs some short-term help with our cashflow. Longer term, we have contracts coming in, but we also have serious unmet short term needs. Rather than just begging for money, we decided we'd rather give something to the Perl community.

The Plan

Back in March, there was a discussion about testing intrfastructure on p5p, with contributions from many Perl community members, including myself. One consenus reached by this discussion was that despite the amazing efforts by people such as Steffen Müller, Abe Timmerman, George Greer, Andreas Koenig, and others I'm unfortunately forgetting, there is significant room for additional, improved smoking infrastructure for the Perl core. Nicholas Clark even went so far as to sketch out some notes on what he would like to see added in this area. (Shortly after this email thread concluded, I started my ill-fated summer project.)

Now, several months later, Tamarou is in the position of desperately needing to trade some time for money. Consequently, we've started a new project on the recently updated Tamarou website. The project has the general outline of what I think needs to be done to accomplish the tasks that Nicholas defined. It has a timeline for how long I expect to take to accomplish these tasks. It also has a place where you can donate some money to making this project happen, if you think this is a good idea. Overall, we need about $5000 USD to make this project feasible.

Frequently Anticipated Questions

1) Why not get a grant from The Perl Foundation?

I love The Perl Foundation. I will try to do anything that TPF President Karen Pauly asks, because I think she works far too hard as it is. That said, I think that the TPF has had a rocky history when it comes to development grants. While stewardship by the current Grants Committe, and projects like the Perl5 Core Maintenance fund are doing an awesome job in moving past that history, I wanted to try something different. I remain open to future TPF involvement, but I hope that Tamarou can show a third way to succeed with crowd-sourced funding for development to support Perl5 core.

2) What happens if you fail?

Then we fail. Publically and with full transparency. I think the project scope is well understood, and it can be reasonably accomplished on the timemline I've laid out -- I've learned my "heroics" lesson -- but if I go over time, then I go over time. If in the end, even after extraordinary effort, the project cannot be accomplised, all my work products will be committed to a public repository and provided for the world to use.

3) Is this really something we, the Perl5 community, need?

I don't know. In March, posters on p5p were excited about seeing it done. I've had private conversations with some of the people it would directly benefit and they didn't seem to think the project was insane. I had to pick something to try, and this is what I picked. If you have a better idea, and this experiment doesn't totally blow up in our face ... we can try your idea next time!

4) How can I help?

First, obviously, you can contribute money. (Seriously: we can really use the cash.) Secondly, there are many tasks I left out of the initial scope of this project to make something I thought could be reasonably accomplished on a reasonable schedule and budget. I have already committed to start documenting these tasks, and as I move through this project I will work on making everything accessible for contributions from the community at large.

By: Chris Prather on 2012-09-25T23:45:00



  1. The summer of 2012, in which YAPC::NA was brilliantly hosted in Madison, WI. ↩

  2. My favorite comment/review of the talk was "Dude needs a nap." At this point, I'm not sure who made the comment, but it was awesome. ↩

  3. One of the best things, for me, to come out of the Moving to Moose hackathon was how it reminded me of all the things I love most about the Perl community. ↩

How to Automate breaking half of CPAN with Dist::Zilla!

So last night I dropped a new module on to the CPAN. Normally this would be a cause for celebration, except it turns out I broke Moose.

A Date with Destiny

If you don't know local::lib, you should. I've been using it on a per-project level using John Napiorkowski's App::local::lib::helper. This works out incredibly well for those nasty internal projects that have hard dependencies on specific versions of modules, or have dependencies on modules that don't want to talk to each other.

I've been using this so much I have a couple scripts setup to make life easier for myself, I just run use-local-lib and it'll setup a perl5/ directory and setup a subshell to make that the default installation target for things like cpanm.

And because I've been incredibly busy learning new things that are totally unrelated to being a developer, Dist::Zilla has been helping me by making sure things happen the same way every time regardless of how long it's been since I'd done release engineering. It helps prevent issues like this.

With Great Automation comes Great Responsibility

So the stage was set last night. I'd decided to cut a release of my latest module that I'd been working on for a client project so that I could actually use it for that client project. Just fire up dzil release, fix the several issues that cropped up with the Git plugin and get it to ship off the latest dist.

Then I notice that it had shipped my local::lib.

This was made worse by the fact that I happen to have co-maint on a lot of modules that I used on a daily basis. Not that I wrote all of them, just that people (until today) thought I was responsible enough to be a bus number for them. So I had co-maint on large portions of my local::lib.


The Fix

The main fix (and the one I didn't do in a timely enough manner) was to run crying to my local PAUSE admin and tell them what I'd done.

What I had done was, immediately when I noticed, issue a delete request for the bad dist, and create a new good dist and upload that. What needed to happen was for a PAUSE admin to force a reindex (and even then doy had to create a new release of Moose) of the affected modules.

Finally, I just needed to teach dzil to prune the perl5 directory so that it never happened again. Adding the following to my dist.ini fixed it.

match = ^perl5

This will make sure that after dzil creates the build directory, it removes the local::lib it copied over from the source directory.

Knowing is Half the Battle

So Dist::Zilla is a huge boon not just to people who manage very large numbers of CPAN dists, it's also nice for people who in-frequently manage CPAN distributions. But with the great power of automation, comes great responsibilty to make sure that it does what you're expecting. I should have taken a minute or two to check that the distribution direction was what I had expected it to be, and when things had blown up I should have gone and talked to someone to make sure that it had been cleaned up properly.

By: Chris Prather on 2012-04-03T13:22:22



I saw the best minds of my generation...

So there has been a recent post that stirred up some commentary. The basic gist is that the author decided to leave Perl because he got tired of living with the constant scolding over 'use strict'. Something that (as he points out in an update) even Mark Jason Dominus has commented on1.

I agree with him. Not about use strict, I actually agree with the people that suggest using more training wheels like strict, warnings, and diagnostics. I think that not only do they help when you're first starting out, they help protect against stupid mistakes when you've been doing this for a decade. No, I agree that the Perl community has managed to make programming less-fun, and I think the comments on his post prove his (and now my) point.

The big reason for leaving Perl, though, was people in the Perl community, who had become annoying scolds.

Most of the comments focus on the 'OMG He is complaining about strict and then using Python!", without pausing for a moment and looking at the deeper issue. As one commenter points out we use strict as a test to identify people who are worthy of our support from those who are un-worthy. We have a lot of these shibboleths, and we can't even agree on them as a community. I've had people file bugs against modules I maintain because they use Module::Install. I've had people file bugs against modules I maintain because they don't use Module::Install. I've watched people get rather nasty in blog posts because an author decided to use Moose, or stop using Moose, or use Mouse, or Moo, or Mo, or M ... well maybe not M.

If we're going to have a reputation for being annoying scolds, we could at least have the decency to come up with an single set of standards to scold people with.

I'd rather however we stop for a minute and remember that there is another developer on the other side of the computer. I've been guilty of ignoring this as much as anybody2. But we're not just losing developers like the author of this article. I've had someone who helped me get started in the Perl community tell me that this article sums up the way he feels. That's two people who have had over a deacde in Perl tell me they moved on because Perl stopped being fun. How many people are there that feel this way and don't say anything?

So here's the deal, the next time you feel you need to complain that someone is using Moose, or not using Moose, or using Dist::Zilla, or using Module::Install ... rather than explaining to them how their decision has personally caused you anguish and has been shown in peer reviewed studies to cause cancer in Kittens, stop. Email them, or message them, or whatever and ask them why they chose that path. They may tell you that they didn't know a better way, that they were just trying something new, or that they need more research candidates for their research studies on curing cancer.

If you can't accept their opinion at that point, ask yourself what you can do to help people become better informed on what the appropriate opinions are in the future. If you can't come up with something simple you can do, ask yourself why you can't contribute to making the Perl community better.

Then submit a talk to the next Perl workshop3 about why you hate kittens.

By: Chris Prather on 2012-02-13T19:05:00



  1. If you have no clue who MJD is you can skip this blog post because you haven't been around long enough to remember when things were different. If you have no clue why MJD's opinion might possibly matter, well ... thank you mjd for reading my blog. ↩

  2. Especially on reddit, if I've been an asshat to you there and haven't apologized ... I'm sorry, for both being an asshat and this crappy apology. ↩

  3. At the time of this writing that is the DCBPW Workshop, and/or YAPC::NA 2012. Both of which I believe are accpeting talks. ↩

Perl Oasis 2012

How to organize a conference in your home town, and then not attend!

So last weekend (January 14th specifically) was the 4th Orlando Perl Workshop aka "Perl Oasis". From the feedback I've seen people generally had an excellent time. Which is good because I missed most of it.

Friday Night Lights

Friday I taught the Moose course to four excellent students, afterwards we had a wonderful welcome party that started in the foyer of the conference area and eventually moved up to the Hospitality Suite that we'd booked for the weekend. People contributed money towards ordering Pizza and Drinks, and everyone hung out until around 2am. Or at least thats when I went to bed. Unfortunately the sleep wasn't to last long.


Take My Breath Away

About 4am my phone rang. I hung up. It rang again and woke me up enough to notice it was my mother-in-law calling. She was the grandparent we had left my son with1, and if she was calling it probably was important. During the night our son Eoin had started having breathing issues and had woken them up coughing and wheezing. He'd reached the point in the night where needed to go to the ER.


Since my wife, Jamie, had partaken a bit more heavily of some of the adult beverages than she'd intended2, I was the one sober enough at 4am to drive across town to the hospital.

My son has had breathing issues since he was born premature. It has been in fact the only lasting effect of the time he spent in the hospital after he was born. So the time I spent on saturday sitting in an ER waiting for his O2 levels to rise to acceptable levels was not unfamiliar. My wife on the other hand woke up to being the lead organizer for a Perl Conference.

Herding Cats

When my wife showed up at the conference venue (happily downstairs from the hotel rooms!) she'd discovered there had been a mis-communication between the staff and the kitchen and the buffet we thought was to be served in the conference foyer was instead being served in the restaurant ... and involved coupons we never received and couldn't give to attendees. Recovering from this only pushed the conference start times back 30 minutes.

The amazing Mark Keating stepped in and helped organize things. This was familiar to him as he'd only just finished being lead organizer for the London Perl Workshop. Between him and Jamie they managed to get talks going and run things until 3pm when my son had been formally admitted to a hospital for observation and I could return to the hotel and switch off with Jamie.

It's Almost the End of the Show

I arrived in time to hang out a little bit before the lightning talks started. Mark again stepped up and provided introductions to the Lighting Talks, and I got to watch several excellent and enthralling talks. This was only a slight problem as I was supposed to be timing the talks and giving notice when they were getting short on time. I got so wrapped up in a few talks I was late giving the notice and a few of them almost ran over.

After the lightning talks came Cory Watson's Keynote. I'd asked Cory to give it last year knowing I wouldn't have to worry about it again. I was proven exactly right, Cory knocked it out of the park. I'd been approached afterwards by people who were absolutely not technical people who told me that the talk was excellent. Hopefully he has a chance to give it again this year at other events! (If you're an organizer this is a blatant hint.)

Thank You and Good Night

So Perl Oasis 2012 turned out to be a success, despite the organizers hectic lives. We had 30 attendees from at least three continents again3, we had 18 talks over two and a half tracks, and we had 3 excellent sponsors:

http://shadow.cat http://dyn.com http://tamarou.com

My wife and I were so busy this fall that we came into this event thinking that perhaps it would be our last. We both had so much fun at the event, despite everything else going on in our lives, that we're ready to go again next year. Mark Keating has even started recruiting volunteers to help us organize it again.

By: Chris Prather on 2012-01-20T12:00:00



  1. We operate under a divide and conquer policy with the kids. The girl went with one grandmother, the son with the other. That way they can't team up on either of them. ↩

  2. I honestly blame Ella for the Absinthe. That stuff is evil. And, despite Casey West's efforts to regulate her intake, Jamie (who rarely drinks) over did it. "I kept trying to give her less and she kept noticing." -- cwest. ↩

  3. This year Breno de Oliveira represented South America, while unfortunately Karen Pauley couldn't make it from Tokyo. ↩

Blackjack in 10 Lines of Modern Perl.

There is this thread on Reddit (and StackOverflow) about what's the coolest thing you can pull off in 10 lines of code. Obviously the first question people have is how do you define a "line", cause unless you have significant whitespace issues you can do a lot on a single line.

If you limit yourself to a line is equal to a single idea or step in an application you restrict things a lot, but it's still amazing what you can pull off. For example, here's a game of Blackjack in 10 lines of code:

use 5.14.1; use IO::Prompt; use List::Util qw(shuffle);
sub deal { state $shoe = [ shuffle map { my $c = $_; map {"$c$_"} qw(❤ ◆ ♣ ♠) } ( 2 .. 10, qw( J Q K A ) ) x 6 ]; push $_[0], shift $shoe for ( 1 .. $_[1] ); $_[0]; }
sub value { my $v; for ( local @_ = @{ shift() } ) { s/[ ❤ ◆ ♣ ♠ ]//; s/[JQK]/10/; $v < 11 ? s/A/11/ : s/A/1/; $v += $_; } $v; }
sub show { say sprintf "%s (%i)", "$_[0] @{$_[1]}", value( $_[1] ) }
my ( $player, $dealer ) = map { deal( $_, 2 ) } ( [], [] );
while ( prompt( "@$player\nHit? ", '-tyn1' ) ) { if ( value( deal( $player, 1 ) ) > 21 ) { show( "Busted!", $player ); exit; } }
while ( say("Dealer @$dealer") && value($dealer) < 17 ) { show( "Dealer busted!", $dealer ) && exit if value( deal( $dealer, 1 ) ) > 21; }
value($player) >= value($dealer) ? show( "Player wins", $player ) : show( "Dealer wins", $dealer );

Simple no?

Okay so this wasn't the most legible code I've ever written, let's run Perl::Tidy on it and step through what's going. The first thing you'll notice is that tidied up the code is 3x longer, but that's still only 30 lines of code.

use 5.14.1;
use IO::Prompt;
use List::Util qw(shuffle);

We start with importing the stuff we'll need, we're going to rely upon David Golden's work to make ArrayRef's work properly with push/shift. This feature was introduced in 5.14 we we'll make a hard dependency on that, and also take advantage of the other modern features this will import (like say and state).

sub deal {
    state $shoe = [
        shuffle map { 
            my $v = $_;
            map {"$v$_"} qw(&#x2764; &#x25C6; &clubs; &spades;)
            } ( 2 .. 10, qw( J Q K A ) ) x 6
    push $_[0], splice($shoe,  0, $_[1]);

The second thought, or major chunk, is dealing cards. This little subroutine is doing a lot in a small space so let's break it out a little.

A deck of cards can be though of as the cartesian product of the values of the cards (2..10, J, Q, K, A) and the Suits (❤ ◆ ♣ ♠). We use nested maps to build this cartesian product. We do it for six decks of cards because that gives the house better odds.

The six decks of cards are shuffled and stored in an ArrayRef inside a lexical variable. We use a state variable so that we don't build a new shoe every time we ask for a new card to be dealt.

Finally we actually deal the cards. The hand is passed in as $_[0], and the number of cards to be dealt is passed in as $_[1]. We just splice off of the shoe and into the hand.

Now that we have a way to deal hands we need a way to calculate the value of a hand.

sub value {
    my $v;
    for ( local @_ = @{ shift() } ) {
        s/[ &#x2764; &#x25C6; &clubs; &spades; ]//;
        $v < 11 ? s/A/11/ : s/A/1/;
        $v += $_;

so the hand is passed in via $_[0], since we're going to munge the value we need to take a local copy of the hand. The idiom local @_ = @_; is what gave me the basic idea.

Once we iterate through each card in the hand we start by stripping off the suit since in Blackjack they're all equal. Then if it's a face card (but not an Ace) we replace it with it's value. Can you spot the bug in the next line?

Aces in Blackjack are a little special, they can be either 1 or 11 depending which one is to the player's advantage. If the value of the hand is less than 11 we'll want the Ace to be worth 11, if the value of the hand is more than 11 we'll want it to be worth 1. In the real world the value of a hand is the same irregardless of the order of the cards, Q 2 A and A 2 Q should both be worth 13, not 23. I spent far too much time trying to figure out how to make that work here, and couldn't come up with anything simple. Patches welcome.

Finally we return the running tally.

sub show { say sprintf "%s (%i)", "$_[0] @{$_[1]}", value( $_[1] ) }

We had a common idiom for displaying a hand with some extra information so we make a simple subroutine here that takes a String and a Hand and prints them plus the value of the hand to STDOUT.

These last four chunks have all been setup for the main game. The game we've implemented is a little different from Casino blackjack. I don't play blackjack at a casino and I'm not a stickler for the rules. I may go through and clean up this up to be more accurate ... but right now "meh".

my ( $player, $dealer ) = map { deal( $_, 2 ) } ( [], [] );

Deal two cards to the player and the dealer.

Now we let the player choose to Hit or Stay. This line is a little convoluted so let's dig into it.

while ( prompt( "@$player\nHit? ", '-tyn1' ) ) {
    if ( value( deal( $player, 1 ) ) > 21 ) {
        show( "Busted!", $player );

First we prompt the user what if they want to Hit. If they choose to take another card check if the value of that new hand is greater than 21. If it is we tell the player they've busted and quit. Eventually the player will either bust or quit taking cards, and it'll become the dealer's turn.

while ( say("Dealer @$dealer") && value($dealer) < 17 ) {
    if ( value( deal( $dealer, 1 ) ) > 21 ) {
        show( "Dealer busted!", $dealer );

According to Wikipedia Dealer's in Blackjack are constrained to always draw if the value of their hand is less than 17. So we draw for the dealer and perform the same check to see if they bust.

Finally if nobody has busted.

value($player) >= value($dealer)
    ? show( "Player wins", $player )
    : show( "Dealer wins", $dealer );

We check to see if the player's hand beats the dealer's hand and show the winner.

All told the original draft of the code took me less than an hour to write, and the rest of the evening to clean up into something I'd be willing to show off. It's this kind of thing that keeps me fascinated by programming, and part of what got me started with it all those years ago.

By: Chris Prather on 2011-12-31T18:00:00



Future Moose Support

There has been a little bit of noise on twitter about the recent policy decision by the Moose core team. Most of it seems to focus on this line:

Moose will be dropping support for perl 5.8 with the 2.06 release (in January of 2012).

Which is stating that nearly a year after support for 5.10 has been dropped by the core perl development team (i.e. perl5-porters), Moose will be dropping support for the version before that. A version that hasn't been supported by perl5-porters since 5.12.0 was released in April 2010, and which hasn't seen a release since December 2008.

If that was all that Jesse had said in the announcement, I would totally understand the tempest in a teapot. Mojolicious recently went through the same reaction, and I've commented on it previously. It isn't, and people seem to be ignoring the entire paragraph that follows that first sentence.

As for what this actually means: we will not be immediately rushing in to start using smart matching and ripping out our existing 5.8 compatibility code. The specified version requirement will stay at 5.8.3. Moose will likely continue to work on perl 5.8 for a good while after next January. What this does mean, however, is that we will not be spending any more time fixing 5.8- specific issues. If critical bugs are found (unlikely at this point, but still possible), we will likely just bump our version requirement if no patch is forthcoming. New features are a fuzzier topic, but if someone comes along and implements a new Moose feature that requires features in perl 5.10, that patch will likely be accepted.

This means that the of current Moose core team, all 9 of us, noone has a vested interest in maintaining 5.8 compatibility1. It means that if you have a vested interest on Moose working on 5.8, that you will need to step up and help support Moose working on 5.8. It means that if nobody from the community steps up to help out that we'll have assume that the interest in supporting Moose on 5.8 is not a priority.

It also means that if people propose feature requests that utilize 5.10 specific code, and nobody steps up to back-port the feature we'll assume that 5.8 support is not a priority and apply the feature patch.

This is as Jesse has said, how Open Source works.

By: Chris Prather on 2011-05-20T12:50:49



  1. Now I own a consulting company, and I would love to have a vested interest in fixing core Moose bugs. I'm pretty sure that Jesse and Dave would be open to having the same happen as well. If this is something that there is interest in, please let me know we can work out some kind of Moose Extended Support License. ↩

The Tyranny of Distributions

The Mojolicious team has deprecated Mojolicious on Perl 5.8. Sebastian has a really good argument for doing this, 5.8's regular expression engine is causing security problems. Considering that Perl 5.8 has been deprecated by the core Perl developers, and that 5.10 will be deprecated when Perl 5.14 is released sometime very soon, dropping support for 5.8 really shouldn't be very controversial.

So it's no surprised that he has seen a lot of push-back. The most eloquent critic has been rassie. The point is that some distributions (notably RedHat Enterprise Linux, and CentOS that mirrors it) haven't yet migrated off of 5.8.

A lot of Perl code runs in closed corporate environments and thus has to obey some rules, like using special software distributions, so [unsurprisingly], a big chunk of those 5.8ers are enterprise Linux distributions like RHEL or SLES.

The standard response to this is incredulity at using the system Perl for anything. While I fully agree that relying upon the system Perl is itself a security risk1, the solution of "Just install perlbrew" leaves a lot lacking. Again rassie states it elegantly:

Nobody in their right mind would have allowed perlbrew on production servers. Nobody in their right mind would allow me to allocate hours and days of developers’ and testers’ time to retest everything with the newest Perl version (you don’t seriously assume legacy code had any amount of reasonable regression tests?)

The standard answer again is to blame the distributions. I know I have complained but as rassie points out modern Perl version simply weren't there when RHEL5 was released.

Perl 5.8 has been released in 2002 and as you see, RHEL3, released a year later, has [caught] up and delivered 5.8. RHEL4 and RHEL5 have seen minor Perl updates, since no major updates for Perl came out in that time. Perl 5.10 appeared half a year after RHEL5 released, so it hasn’t been included, Perl 5.12 has appeared roundabout at the same time as RHEL6 beta, so only 5.10 could have been shipped.

But this obscures the real problem. One that Sebastian points out in the email thread about deprecating Mojolicious on 5.8.

Perl 5.8 is no longer supported by the community, RedHat will keep it compiling on their platform but nothing more, these bugs will never get fixed in the 5.8 family. (http://rt.perl.org/rt3//Public/Bug/Display.html?id=49956)

It's wonderful that RedHat has a 7 year support license for RedHat Enterprise Linux. That means absolutely nothing for Perl. RedHat doesn't promise to even maintain security patches for Perl for 7 years. If your company depends upon Perl, the RedHat support license is only half the story.

So what then is the answer? Well the best answer would be for the companies making promises of 7 years of support to actually provide support for those 7 years and to step up and make sure that security patches and what not are applied to Perl 5.8. That isn't going to happen.

An answer could be that firms that depend upon Perl realize that Perl has a separate support license from the Operating System and to employ someone, or hire a company who offers a support license for Perl to maintain Perl 5.8 for however long they need. That probably won't happen either.

The answer is not to blame people who volunteer their time for not being mindful of your distribution environment. To be frank that isn't their problem. The guilt/feel-good motivations of Open Source only work so far. I personally am tempted to drop support for any unsupported Perl version for my own modules (and to recommend to the communities, and clients I work with to do the same). None of those communities has the ability to support deprecated versions of Perl independently. My company certainly doesn't employ anybody with sufficient knowledge to contribute to the current version of Perl, let alone be able to maintain a legacy version of Perl single handedly. So what are we left with?

We do what the Perl core team does (under Jesse Vincent's admirable leadership). We try to maintain compatibility as best we can, while trying to keep things moving forward to be more useful, secure, and robust. This is what Sebastian is doing with Mojolicious2.

If you have a need to support a legacy version of any of my modules, I am wildly supportive of you forking that to maintain compatibility with your environment. I don't work in your environment, I'm not motivated by guilt (or money) enough to pretend that I do.

By: Chris Prather on 2011-05-08T12:39:00



  1. Apple, for example, has consistently broken their own system Perl on OSX making using it for even development unreliable. The current Perl in Snow Leopard in fact cannot build XS modules using the current release of XCode4 without tweaking the environment in an obscure way.  ↩

  2. Don't believe it is pure altruism. Sebastian has much snarkier reasons. "Just to make it absolutely clear, [I] have no intention to give other Perl web frameworks a competitive advantage."  ↩

The PSGI is the Limit

Miyagawa has recently linked to a bunch of forums where he has encountered a lot of push back against PSGI. The argument basically goes "We're using CGI/mod_perl/FastCGI just fine and it works for us, why should we change?" Let me tell you a couple of stories.

For the last year and a half I consulted on a large web application. It was a closed application but based on Catalyst and used mod_perl as a deployment. The site had a decent amount of traffic but with a combination of nginx as a front-end proxy, proper caching, and a CDN the systems we had were handling things just fine.

The lead systems guy was often in the mood to experiment with alternatives to see if we could get better performance out of the cluster of machines that ran the site. Because we happened to be using Catalyst, and thus Catalyst::Engine, we suggested that he try moving to FastCGI and dropping Apache out of the mix. So he took a box out of commission, re-jiggered it and tried it. There was a 30% reduction in the system load.

30% … nearly 1/3 as much load … that meant by just re-tooling our application stack with no actual changes to the code base we could eliminate 1 out of every 3 servers. We saved the company 30% of our hosting costs by simply changing the deployment scenario all because with Catalyst::Engine we could try a new deployment scenario with no effort.

This is where PSGI saves people money. PSGI is the generalization of Catalyst::Engine and HTTP::Engine and several other projects over the years (yes dating all the way back to Apache::Request and Apache::PerlRun which emulated a CGI environment in mod_perl). It de-couples the application deployment logic from the business logic and allows you to perform trivial changes to the deployment.

The second story I wanted to tell you was this. Way back in the day I was playing around learning POE. Someone had written a POE server, POE::Component::Server::HTTP and there was a page on the POE wiki talking about how to run CGI applications under it. The code was incomplete because it didn't really implement the CGI environment, it just did the GET and POST stuff. So I went and read the Specs for CGI (they're ancient-by-web-standards NCSA webserver documents) and sorted out which pieces needed to be glued into where.

I have to tell you it wasn't difficult but it certainly isn't the most elegant code I've written. The same basic idea was taken on as HTTP::Request::AsCGI and judging by the 14 releases that package has had over the last five years it's not exactly edge-case free1.

PSGI as a specification is much simpler to implement for a Perl application than the CGI environment. PSGI is at it's core a subroutine that takes a HashRef and returns an ArrayRef. Now I hear you crying out that CGI is just that easy, but really it's not. CGI is a pollution of environment variables and a system call (or something that fakes system call that by dumping it's output into STDIN). Tell me honestly as a programmer, which is easier: a subroutine dispatch, or faking a capture of the output of a system call?

So while CGI may be "good enough" for you (hopa!) there are cases where it's not "good enough" for the people implementing the tools. While you may never ever ever move off of CGI, FastCGI or mod_perl, that doesn't mean that something better won't ever be invented. It also doesn't mean that what you're using is the best possible solution for your application, but you'll never know that because you didn't see a reason to abstract your deployment in such a way that you can try out alternatives quickly and easily.

By: Chris Prather on 2011-05-08T03:34:45



  1. Think that's not sufficiently bad? Look at the hoops people suggest you jump through for CGI support under nginx http://wiki.nginx.org/SimpleCGI ↩

Information Hiding or how I learned to hate state and love behavior...

The conversations about documentation of Object Oriented Perl brought up a classic disagreement about the nature of encapsulation. It doesn't help that the term 'encapsulation' is overloaded.

Encapsulation is the wrapping of an object's data, also know as it's state, with guard behavior. This is so the state cannot be easily changed without the object being complicit. Think of it as the warranty sticker on an object, while you can (especially in Perl - through various levels of heroic effort depending on the object data type) violate the encapsulation, you break any guarantees that the object will continue to function as advertised. Just as with a broken seal, or a water damage indicator if we are talking Apple products, you get no guarantees from the manufacturer.

For many people, especially Geeks who are more often prone to violating a warranty as soon as they get the wrappings open. This may sound like a pain and hassle. In many ways it is a hassle, intelligent people should be allowed to take risks and do what they want or need with property they own. Even if that property is a copy of a project released under an Open Source license. On the other hand, the warranty seal really is a savings because you no longer have to worry about your object working correctly. So long as your doing what it says on the box, or documentation, it will do the right thing. If it doesn't you can rightly complain to the manufacturer and expect some level of help.

What then is the other definition of encapsulation, Information Hiding?

It really is just another step further in this same direction. Information hiding says that not only should nobody have a warrant to poke into the private parts of the object( including it's state), nobody even be aware of (or care about) how the inside is implemented.

Let me use an example that came up that I think illustrates it well. An example came up that we use $foo++ to increment the value in $foo. This suggests we should be able to use $obj->foo++ to increment the value of the foo attribute in $obj. With proper overloading and use of lvalues (and possibly ignoring some of the lurking dragons in Perl's implementations of these) it is possible and will keep true to the first definition of encapsulation.

This sounds really reasonable at first, and I admit I thought for a bit "well why not?" But I realized soon enough that what this did is created more work for myself. It meant I and any users of my objects were forced to violate Larry's Law of Laziness.

But, you say, how does it make us less Lazy? It reuses an idiom we already know. The quick dismissal is that you can't handle multiple arguments, for example in a table with cells. This is rightly countered with $obj->get_cell(1,3)++. Really the problem is more subtle.

By making a distinction between state and behavior we are forced us to be aware that similar things are treated differently. Even if we have proper encapsulation and all state is guarded with some behavior, we're still forced to be aware that some thing's behave like values; they increment, decrement, and are assigned with operators; while others will behave like ... well behaviors, that is like methods.

This then is the problem that information hiding is protecting. It means we have a uniform API, and it doesn't matter how the underlying implementation is handled. It means that I am protected from deciding at some future point that a given value is a poor choice and I can re-factor it out. It means that I don't have to play "Language Designer" and worry about how the increment operator plays with pure methods in my objects (what would $obj->book_hotel($client, $hotel)++ mean?). It means in short that I can in fact trust that my warranty is what I claim on the box.

By: Chris Prather on 2011-04-12T14:08:02



Party like it's 1979

So recently I've been playing Lacuna Expanse more than I probably should be. It's an interesting game with a lot of other Perl programmers involved, so the community feeling is very familiar.

One of the things that Lacuna Expanse does that I haven't seen in other games, not that I game a lot1, is they expose their server API fully. This means not only can you use the official JS/HTML Client, or the iPhone client, or the Adobe AIR client, but you can write your own scripts to target the API. Shortly after the game was formed, tsee created Games::Lacuna::Client.

After that there was an explosion of small Perl scripts doing everything from building reports of ships in the empire, to doing full automation of your account through a limited AI "Governor".

Earlier this week in the in-game chat someone suggested there should be a text-based version of the game. I suspect that the suggestion was in jest, a text-based client to a Web Based game that has a GUI already is ... well awesome but silly. It did however get me thinking. With Games::Lacuna::Client it shouldn't be that hard to write. Two days later...

Well here is a Screen Shot:

Screen Shot


The code is still in developer release mode. It may never get beyond that point. If you'd like to get started with Games::Lacuna::MUD simply do the following.

On a box with Perl 5.12.22 installed download a copy of this Games::Lacuna::MUD either by cloning it or downloading a tarball.

I'm gonna assume you have CPANMINUS installed. If not it use your own preferred client or install cpanm from the web.

> curl -L http://cpanmin.us | perl - --self-upgrade 

Make sure you have Dist::Zilla installed, this will make installing the dependencies easier.

> cpanm Dist::Zill

Once Dist::Zilla is installed simply do the following to install the dependencies required for Games::Lacuna::MUD

> dzil listdeps | cpanm

Once the dependencies are installed you will need to have a developer API Key that you can acquire from this site.

With the developer key you can create a configuration file for Games::Lacuna::Client.

api_key: [KEY]
empire_name: [EMPIRE]
empire_password: "[PASSWORD]"
server_uri: https://us1.lacunaexpanse.com/

Save this as $HOME/.le-mudrc and you can start the MUD client with the following

> perl bin/le-mud.pl

Some basic MUD commands work: look, go planet, go building, leave building, quit

Beyond this the commands are still rudimentary. There is no help system because I wasn't happy with the on that I had and haven't come up with a slick way of integrating a cross cutting concern like that. You are free of course to view the source.

I'm really happy with the design of this project, I thought I'd take a few blog posts to explain some of the tools I used to throw it together in about 2 days of work and how Moose and CPAN really helped make it work quickly and be fun.



  1. Actually I tell people that my "game" is called Perl. When I want to do something creative and non-work, I hack on throw away side projects. I've got an addictive personality and I always feared I would waste far too much time playing, which is why I've never started. ↩

  2. I'm actually really lazy, use 5.12.2; is part of my stock boiler plate for personal scripts though I don't think I use anything that wouldn't be compatible under 5.10. By: Chris Prather on 2010-12-31T00:00:00 ↩