Critical Hit

Last night I braved Winter Storm Juno to venture out to Albany Perl Mongers’ technical meeting in East Greenbush.  Our special guest star Jeff Thalhammer had agreed to teleconference in from San Francisco to talk us through Perl::Critic.  This arrangement worked pretty well for us, with Jeff able to chat with the small number of us that had braved the storm and answer our questions. The only flaw with the setup was Jeff wasn’t able to try the pokemon cupcakes I’d baked. Bring on cupcake-over-ip technology is what I say.

I’ve been using Perl::Critic for many years now, and I wasn’t sure I would get much out of the technical meeting, but I was very wrong. Jeff was able to give several tips, answer questions, and point out a bunch of improvements that I was unaware of since I first started using Perl::Critic years ago.

only

The biggest win for me was learning about using the only option directly in a .perlcriticrc itself. This allows you to only run the rules specified in the critic file rather than any installed rules and is awesome for continuous integration test suites running off our in-house .perldcriticrc because if a new rule gets installed (due to an update our distribution dependencies) we don’t start automatically using it (and failing it) without some sort of review.

verbose

The various levels of verbose output that Perl::Critic’s verbose options now provides are very helpful. Bumping the output to level 8 (with --verbose=8) helpfully tells you the name of the policy that you’re violating, which is useful if you want to disable it with a ## no critic (...), or tweak the .perlcriticrc or simply read the documentation for the module so you can better understand what the policy is complaining about

profile-proto

My ancient personal .perlcriticrc file is getting a bit long in the tooth. Not only has my coding style changed over the many years as I’ve learned more about Perl, but Perl::Critic itself has improved introducing new policies both in the core distribution and on the CPAN itself. This is why I was excited to learn about the profile-proto which can spit out a fully-documented default .perlcriticrc

Let’s Go Shopping

Jeff took us on a brief shopping tour of the CPAN to show us some of the cool new policies that are available. Some standouts include:

Thanks

Thanks to both Jeff for taking the time to talk to us, and to Patrick Cronin for once again organising the meeting, providing pizza and all the other thankless stuff he does to organise our meetings.

Getting Choosy

Today I released a new version of Mac::Choose which wraps the choose command line utility. Basically this lets you, from Perl, pop open a fuzzy match dialog like quicksilver, alfred, et al. This is probably best shown rather than explained:

use Mac::Choose qw(choose);
print choose qw(
      red
      orange
      yellow
      green
      blue
      indigo
      violet
) or die "User canceled selection";

choose_example_demo

The exciting thing about this release is that while previous versions required you to go to Tiny Robot Software’s website to download a copy of choose, this version of Mac::Choose ships with the choose binary and installs a copy alongside the Perl module.

Using File::ShareDir

In order to handle the intallation of the binary in a place where my code could once again find it I altered my distribution to use the File::ShareDir infrastructure. Essentially this infrastructure comes in two halves, an installer to install things in the shared dirctory and a module that can give you access to the files again.

In my Module::Intall powered Makefile.PL in order to use Module::Intall::Share I simply had to add the line:

install_share;

This installs everything in the share directory of my distribution (which just contained one file, the choose binary) when you make install.

The changes to my module were also very simple:

use File::ShareDir qw(dist_file);
our $executable_path = dist_file("Mac-Choose","choose");

Testing

After those changes, everything worked flawlessly…apart from the test suite! The problem is that until the module is installed the files aren’t in the shared directory, and traditionally we test a module before we install them.

This isn’t insurmountable however, we just need to make some changes to our tests to quietly override File::ShareDir’s functionality with that from Test::File::ShareDir:

use File::Spec::Functions qw(:ALL);
use FindBin;
use Test::File::ShareDir (
    -root => catdir($FindBin::Bin, updir),
    -share => { -dist => { "Mac-Choose" => "share" } },
);

Posted in 1

Permalink 2 Comments

Internet Famous

Did I ever tell you guys the story of how I once made the front page of imgur with a Perl script?

As we’re all aware, imgur is a imaging sharing network traditionally dedicated to such topics as funny cat photos, internet memes and other recycled content often direct from its sister site reddit.  It’s internet fluff in the best possible way, and what I like to browse when I’m eating lunch and I need to disconnect my brain after a morning of coding.  While it’s got a minority of hardcore technical members, it’s not at all known for it’s technical content due to posts being promoted based mostly on up and down votes given by the masses;  As far as I know I’m the only person ever to get to the front page with actual code.

So how did I end up posting code of all things to imgur? Well, like most good Internet stories it started like this:

One lunchtime I saw a front page post featuring an image claiming that startling was the only nine letter word that you could remove one letter at a time and still get a valid word (i.e. starting, staring, string, sting, sing, sin, in, I.)  I was pretty sure that wasn’t right and there must be others. So I did what any Perl programmer does in this situation.  I wrote a Perl program to prove that wasn’t true:

And then for giggles, I posted the above image back to imgur.  Not exactly my best code, but I wrote it in about five minutes flat.  Five hours later it hit the front page and I had done my duty.

Regexp::Debugger

One of the topics that I had scheduled for the Perl Advent Calendar this year that didn’t finally make the cut was Regexp::Debugger (It might make it next year, but let’s all pretend I never made this post if that’s the case.)

I really wanted to write an article on Regexp::Debugger because it has such wow factor.  You just stick a line in the source code and bam instant visual debugger.  Suddenly I was finding out in minutes what was wrong with the regular expression that I’d spent half an hour figuring out writing numerous tests.  Sometimes there’s no substitute for getting in there and seeing what’s going on.

The problem with the article is that that’s pretty much all I could say about the module.  It’s almost too simple to use – there’s just nothing else to comment on.  Go.  Go use it.  You won’t regret it.  Hmm.

The other big problem is that it’s almost impossible to describe in words how to use the debugger.  It’s something that works best in a screencast or something similar and we’re not (yet) set up to include those kinds of things in the Perl Advent Calendar.  The article on ack had a couple of animated gifs, but I’m unsure if the one I prepared for Regexp::Debugger really conveys what’s going on without an audio track.  Still, for posterity, here’s the gif I prepared:

Regexp::Debugger demo gif

Posted in 1

Permalink 3 Comments

Perl Advent Calendar 2014 Stats

The Perl Advent Calendar is finally done and dusted for another year (apart from the typo corrections – there are always typo corrections.)  Which is lucky, since I committed the last submission just two days before Christmas Eve.

Let’s look at some statistics shall we?

The advent calendar is a team effort:

  • Total articles: 25 (24 articles + xmas day)
  • Articles written by people than me: 13
  • Total number of authors (including me): 13
  • Number of Pull Requests For Typos (so far): 8

It’s big:

  • Total number of lines: 5,318
  • Total number of words: 27,323
  • Total number of graphics: 7 (including two animated gifs)
  • Longest articleChristmas Eve’s Article (an epic 745 lines)
  • Perl examples: 159

It’s Perl:

  • References to Perl: 171 
  • References to Moo/Moose: 38
  • References to PHP: 2 (in the example about finding and deleting all the php code)

It’s fun

  • References to Santa: 38
  • References to Elves: 44

So, maybe now I’m not writing 2,575 lines (12,310 words) into the advent calendar (and copy editing and adding content to the other articles) I can finally get back on the Perl Ironman bandwagon in time for new year? Jarvis, load my blog editor…

Posted in 1

Permalink 1 Comment

Tell me more, tell me more

A new version of Test::DatabaseRow has just escaped onto the CPAN, with a minor new feature verbose data to make working out what went wrong in the database test even easier when the worst happens

In a nutshell this feature allows you to output in diagnostics all the results the database returned (not just listing the first thing that didn’t match, which is the default thing row_ok does in a similar way to Test::More’s is_deeply does.)

In other words instead of writing this:

    all_row_ok(
       table => "contacts",
       where => [ cid => 123 ],
       tests => [ name => "trelane" ],
       store_rows => \@rows,
       description => "contact 123's name is trelane"
     ) or diag explain \@rows;

You can just write this:

    all_row_ok(
       table => "contacts",
       where => [ cid => 123 ],
       tests => [ name => "trelane" ],
       verbose_data => 1,
       description => "contact 123's name is trelane"
     );

Or even just write this:

    all_row_ok(
       table => "contacts",
       where => [ cid => 123 ],
       tests => [ name => "trelane" ],
       description => "contact 123's name is trelane"
     );

And turn on verbosity from the command line when you run the tests

TEST_DBROW_VERBOSE_DATA=1 perl mytest.pl

Mavericks, XCode 5 and WWW::Curl

Sometimes you go through a lot of pain trying to get something to work, and you just need to write it down and put it on the internet. You tell yourself this is useful; You’re doing it so that others can find your words and solve the problem too. In reality, it’s just cathartic. And who doesn’t like a good rant?

So What Broke?

I recently updated my Mac to Mavericks (OS X 10.9). Overall, I like it…but it broke something I care about. It broke libcurl’s handling of certificates., and in so doing broke my install of WWW::Curl also (since it’s a wrapper around the system libcurl.) This is remarkably hard to diagnose, because it just seems like the servers have suddenly stopped trusting each other (when in reality libcurl has just started effectively ignoring the options you’re passing to it.)

Now, WWW::Curl (and its working certificate handling) is a dependency of some of the code I’m using. Worse than forcing me to disable certificate security, I actually need to identify myself to the server with my own cert. Just turning them off and running insecurely won’t work.

Installing libcurl

I’m not a great fan of installing software from source on my mac after having been bitten by fink and it’s kin numerous times in the past. This said, homebrew is actually pretty darn nifty, and can be used to install libcurl:

brew install curl   

Wrrr, clunk, clunk and zap, I have a non broken curl in /usr/local/Cellar/gcc47/4.7.3/bin. Hooray! This one actually deems to listen to the command line options you pass it!

Installing WWW::Curl

Now all we have to do is install WWW::Curl and link it against this libcurl, right? Well, I did this:

wget http://cpan.metacpan.org/authors/id/S/SZ/SZBALINT/WWW-Curl-4.15.tar.gz
gunzip -c WWW-Curl-4.15.tar.gz | tar -xvf -
cd WWW-Curl-4.15
export CURL_CONFIG=/usr/local/Cellar/curl/7.33.0/bin/curl-config
perl Makefile.PL

And things started to go wrong:

The version is libcurl 7.33.0
Found curl.h in /usr/local/Cellar/curl/7.33.0/include/curl/curl.h
In file included from /usr/local/Cellar/curl/7.33.0/include/curl/curl.h:34:
In file included from /usr/local/Cellar/curl/7.33.0/include/curl/curlbuild.h:152:
In file included from /usr/include/sys/socket.h:80:
In file included from /usr/include/Availability.h:148:
/usr/include/AvailabilityInternal.h:4098:10: error: #else without #if
        #else
         ^
/usr/include/AvailabilityInternal.h:4158:10: error: unterminated conditional directive
        #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_6
         ^
/usr/include/AvailabilityInternal.h:4131:10: error: unterminated conditional directive
        #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_5
         ^
/usr/include/AvailabilityInternal.h:4108:10: error: unterminated conditional directive
        #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_4
         ^
4 errors generated.
Building curlopt-constants.c for your libcurl version
Building Easy.pm constants for your libcurl version
Building Share.pm constants for your libcurl version
Checking if your kit is complete...
Looks good
Writing Makefile for WWW::Curl
Writing MYMETA.yml and MYMETA.json

That Ladies and Gentlemen is the sound of Apple’s compiler sucking. You see, not so long ago I upgraded to XCode 5 and apparently this no longer ships with gcc. Uh oh.

(I don’t show the errors you get when you make and make test, but be assured it’s all downhill from here)

Installing gcc

I suspect I could have just re-downloaded XCode 4 and then used xcode-select. But I didn’t. Let me know if that works, okay? This is what I actually did:

brew install gcc47

Then I waited a long time (while doing something else productive instead.) Finally when I was done I had to manually edit the Makefile.PL to use the right preprocessor:

perl -pi -e 's!cpp"!/usr/local/Cellar/gcc47/4.7.3/bin/cpp"!' Makefile.PL
perl Makefile.PL

(yeah, it’d be nice if they’d been some sort of option for that.) Then I altered the resulting Makefile for good measure too:

perl -pi -e 's{CC = cc}{CC = /usr/local/Cellar/gcc47/4.7.3/bin/gcc-4.7}' Makefile

And then I could build it all.

make
make test

Of course, it still got errors. But they’re not new errors. So I pretend I didn’t see them and install anyway.

make install

I hate computers sometimes.

Posted in 1

Permalink 3 Comments

Follow

Get every new post delivered to your Inbox.