By genehack on 20 May 2012

There's Moose in them there hills...

This one time, at band camp in #moose:

11:23 < sartak> 7% of CPAN directly depends on Moose
11:24 < sartak> 1655 dists of 23,808
11:26 < genehack> sartak: what's the percentage that indirectly depends?
11:26 < sartak> dunno. I'd like to know though
11:27 * sartak got those numbers from and quick inspection 
      shows that it's counting only direct dependents (see the Dist::Zilla territory)
11:32 < genehack> that seems like something that should be trivial for somebody 
      who knows the MetaCPAN API well...
17:32 < genehack> sartak: 2334 dists have direct or indirect Moose deps
17:33 < genehack> that's 9.8%
17:34 < genehack> (at least if my stupid abuse of the metacpan search API didn't 
      have a thinko.)

(code here)

Update on 26 May 2012: Ran the same code for Moo and Mouse -- they have 263 and 270 dependents, respectively. That's approximately 12% of CPAN, all told, depending on one of these modules...

Tags: moo , moose , mouse , perl
By genehack on 09 May 2012

CSA week 1

Yesterday was our first Sandy Spring CSA pickup of the year -- we've got 24 more before we're done, running through October 22nd. I don't know that I'll stick with doing this every week (Historical Record Magic 8-Ball sez: "HAHAHAHAHAHAHA"), but here's what we got and what I'm planning on doing with it:

First, what was in the box, in no particular order:

  • 1 bunch baby scarlet turnips
  • 1 bunch red radishes
  • 2 bunches collard greens
  • 1 bunch scallions
  • 2 heads of lettuce (1 "butterhead", 1 "green leaf")
  • 1 bunch purple mizuna
  • 2 heads baby bok choy
  • 1 bunch of carrots

(There was another big head of bok choy in the box, but I swapped that for a second bunch of collard greens out of the Swap Box.)

Here's my menu list for the next week, which manages to use everything except the greens from the carrots, radishes, and turnips (and even those will probably migrate into a salad mix at some point...)

  • Wednesday: lettuce salad with mushrooms, radishes, cherry tomatoes, grilled chicken, and balsamic vinaigrette
  • Thursday: collard green stew with chorizo and garlic
  • Friday: hamburgers, roasted turnip fries with Parmesan
  • Saturday: carnitas tacos con guacamole y pico de gallo (requested by @MrsGenehack for Mother's Day...)
  • Sunday: bok choy / mizuna / tofu stir fry + cooking down chicken stock (this is where the carrots are headed)
  • Monday: lettuce salad with mushrooms, radishes, grilled steak, and balsamic vinaigrette (and maybe some additional greens)
  • Tuesday: mexi-melt chicken surprise

(Wikipedia has a nice CSA article if you're all "WAT.")

Tags: CSA , cooking
By genehack on 29 Apr 2012

Yak Butter Makes The Best Shaving Cream

This morning, I was finishing off my coffee and reading the morning email -- as you do -- when I came across a bug report for Git::Wrapper, a module I maintain. It turned out that a recent change I'd made to my workflow (archiving older releases in my working tree) had resulted in the archived releases being included in the version of the software I'd packaged and put on CPAN for distribution.

Whoops! I needed to fix the problem and get a new release uploaded to CPAN as soon as possible, and since it was a quiet Saturday morning and I had about an hour free before I needed to run some errands for @MrsGenehack, I didn't expect it would be a big deal. I use Dist::Zilla to help me package up Git::Wrapper for distribution, so I figured it would just be a simple matter of tweaking the configuration in the dist.ini file in my working copy and then releasing a new version to CPAN. How long could it take, really?

(Enter First Yak, stage right, with bouffant rampant...)

I tried a couple of different approaches to changing the configuration so that it would do what I wanted, and couldn't quite get the syntax right. Instead of continuing to pound my head into a wall, I hopped onto the #distzilla channel on and asked for help. RJBS (author of Dist::Zilla, current Perl pumpking, and generally nice guy) quickly pointed out where I was going wrong and got me on the right path.

I was working on the problem in a MultiTerm buffer in my editor, Emacs. I'm giving a talk on editor tweaks for more effective programming at YAPC::NA this year, and as part of prepping for that, I'm trying to do as much work as possible inside my editor. This was working great for this particular problem -- I could make changes to my dist.ini file and quickly jump over to the terminal window to run dzil commands and verify the distribution was getting built correctly.

This was working really well, except that I kept getting distracted by some highlighting irregularities -- and since the talk was on my mind, I realized I wasn't going to be able to present at YAPC with those ugly background glitches present. Obviously, taking a couple of minutes to clean that up would be time well spent...

(Enter Second Yak, stage left, somewhat hirsute than previous yak...)

Since most of the highlighting problems seemed to be around the color highlighting in the output of the ls command, I spent a while poking at the dircolors config file I use. I copied this from someplace on the Internets and I've never really taken the time to understand it -- it just worked -- so this was mostly poking of the "change something, see what happens" variety. After a few minutes of failing with this approach, I started to wonder if I was barking up the wrong tree. A bit of DuckDuckGo-ing later, I made a quick tweak to my Emacs config, which fixed the highlighting problem.

(Exit Second Yak, now smooth and free of hair)

That taken care of, I returned to the issue of the Git::Wrapper distribution problem. Before I got diverted by the Emacs shell issue, I'd noticed a few other things in the dist.ini file that I could improve. I took care of that, built a new release, and uploaded it to CPAN. I let the bug reporter know, and closed out the ticket.

(Exit First Yak, now also denuded.)

One of the changes I'd made to the dist.ini was updating the metadata to point to the new Git::Wrapper homepage and to the issue tracker for Git::Wrapper on Github. The MetaCPAN site uses this information to set up the links in the sidebar on the Git::Wrapper release page, so I hopped over there to verify that I'd done everything correctly.

All the links were working correctly, but a Github specific popup was appearing over my homepage link -- which seemed wrong. I jumped on the #metacpan channel to see if this had already been reported, and ended up having a short conversation with MST that resulted in me opening an issue ... which I ended up assigning to myself. (MST: manipulating people into open source contributions for fun and profit.)

(Enter Bonus Yak, descending from the rafters and bearing a strong similarity to MST, at least on the hairdo level... )

I looked at the issue briefly, but as I'd now used up about 1.5 hours of my free hour, I had to let it sit briefly while I took care of those errands. Once I got back, I spent another 30 minutes figuring out the issue. After I was sure I'd got it taken care of, I sent in a pull request, which has since been merged -- the bug is no longer visible on the MetaCPAN site).

(Exit Bonus Yak, freed of hair and looking not unlike MST would have if he hadn't backed out of the "transparent" option when losing the Iron Man Perl challenge...)

Anyway, that's my Saturday morning - three yaks shaved, 2 patches to open source projects, 1 editor config tweak, and some good raw material to fold into my talk. Hope you enjoyed the tale...

(For those of you wondering about the yak thing, "yak shaving" is a geeky way to describe what happens when you're trying to accomplish one thing, but get diverted off on solving a chain of seemingly unrelated problems instead.)

(Hat tip to Josh paperbits DiMauro for the title...)

Tags: emacs , git , git::wrapper , github , metacpan , perl , yaks , yapc
By genehack on 15 Jan 2012


I apologize for the lack of recent Jacquard entries -- I had a few posts buffered up with the intent that I would be able to keep regularly posting even if I couldn't maintain a regular rate of writing and developing -- but then Skyrim came out, and my buffer got empty, and well, yeah. Here we are. I hope to pick up the project and the writing again now that the end-of-year/beginning-of-year madness has now mostly died down, so watch this space.

(ObSkyrim link: @SkyrimMom)

Tags: jacquard , perl , skyrim
By genehack on 15 Jan 2012

Cleaning out the buffer

  • Like Girl Talk? Like dance? Just like cool shit? Go watch all the Girl Walk videos. Right now.
  • It's okay, really. I'll wait. Go watch that shit.
  • This is a really good article about the principle of mise en place. Lots of application to stuff beyond cooking. (And if you're going "mise what?", then you should certainly read it.)
  • Excellent, excellent inspiring videos from makers of things. If anybody is interested in giving me a very expensive gift, those knives look to be the shizzle. (Link via gphat.)
  • Future tattoo material.
Tags: dance , development , maker , tattoo
By genehack on 07 Nov 2011

Tab dump // 20111107

  • Thanks to Gabor for the Jacquard shout out in the latest Perl Weekly. If you're into Perl, you should subscribe to this newsletter, it's a good roundup of Perl-related stuff from around the web.
  • MongoDB sucks. No, it doesn't. (Former link from everywhere; latter from the comments over at Flutterby.)
  • Charlie Stross on Evil Social Networks. Quoted for Truth: "If you're not paying for the product, you are the product."
  • Be On Fire - "YOU. MUST. BURN."
By genehack on 07 Nov 2011

Jacquard 04

Since our previous installment got us [users and authentication][lastinstallment], we're ready to start adding support for various services. One of the features of Jacquard -- one of the main points of Jacquard, actually -- is interacting with multiple services. To make that possible, we've included the accounts attribute in our User class:

# this attribute is going to contain info about all the services
# this user has configured -- i.e., there will be one for Twitter,
# one for Facebook, etc.
has accounts => (
  isa     => 'KiokuDB::Set',
  is      => 'ro',
  lazy    => 1 ,
  default => sub { set() },

Before we start actually writing the code for the things that are going to be inside those accounts attributes, it's worth stepping back and thinking about what the data we want to store looks like, and how we can best structure our classes to help us manipulate that data.

Ideally, what we want -- and again, this is a reflection of the underlying raison d'etre of Jacquard -- is to be able to interact with all the different services we support in the same way without having to worry how each individual service handles fetching new posts, or writing a new post out. In other words, to be able to do something like this:

# warning: pseudocode
foreach my $account ( $self->accounts->members ) {

# or even
my $new_post = get_new_post_from_user();
foreach my $account ( $self->accounts->members ) {
  $account->post( $new_post )

read more

Tags: catalyst , jacquard , kioku , perl
By genehack on 06 Nov 2011

Achievement Unlocked


I started running some time in the late summer of 2010, doing the Couch To 5K program. I'd tried to start running a few other times, and I always had issues with shin splints that would prevent me from establishing any sort of routine. This had been the case for as long as I could remember -- I ran track in my senior year of high school, and I had shin splint problems then too.

The thing that fixed those problems for me was this pair of Vibram Five Fingers KSOs. Running in these hurt at first too -- but it was a different kind of hurt, a more manageable one, and one that got less the more I ran -- the complete opposite of my shin splint problems, in other words.

My last run in these was the Marine Corps Marathon 10K. It was a cold, wet morning, and that hole you can see in the sole of the right shoe didn't do me any favors -- but I finished the race. Seemed like a good time to let these tired soldiers get some rest, so today I picked up a new pair of TrekSports. I'm hoping the slightly thicker sole and treads on the bottom will let me explore some trail running this spring -- and who knows, there's a local half marathon in May...

Those of you that aren't familiar with the Vibrams, or the idea of minimalist running, may want to check out this NYT article for some background. I can't say enough good things about these shoes; they've made it possible for me to run and enjoy it, and that's just awesome.

read more

Tags: fitness , running , vibram five fingers
By genehack on 01 Nov 2011

Jacquard 03

In the [last installment][lastinstallment], we created Jacquard::Schema::User to describe a Jacquard user, and used Jacquand::Model::KiokuDB (and a helper script) to persist User objects to storage. This time around, we're going to create our [Catalyst][catalyst] app and hook up authentication.

So, first step: create the Catalyst application. The helper makes this trivial:

$ Jacquard::Web
created "Jacquard-Web"
created "Jacquard-Web/script"
created "Jacquard-Web/lib"
created "Jacquard-Web/root"
[ couple dozen more lines elided ]

Unfortunately, there's no easy way to tell it "I'm creating this Cat app as a part of a bigger project" -- so after creating it, you have to manually shuffle the files around to get them into the right place. The Catalyst files also come with quite a bit of templated stuff in them that we don't need (POD skeletons and the like), so cleaning that up and getting the code into line with your personal coding style should be done at this point. Once that's all done, checkpointing into revision control is a good idea:

$ git ci -m"Create Catalyst application" 
[03-catalyst 3c20771] Create Catalyst application
 11 files changed, 300 insertions(+), 0 deletions(-)
 create mode 100755 jacquard_web.psgi
 create mode 100644 lib/Jacquard/
 create mode 100644 lib/Jacquard/Web/Controller/
 create mode 100644 root/favicon.ico
 create mode 100644 root/static/images/btn_88x31_built.png
 create mode 100755 script/
 create mode 100755 script/
 create mode 100755 script/
 create mode 100755 script/
 create mode 100755 script/

Next, we're going to use [CatalystX::SimpleLogin][simplelogin] to add authentication to the application, following the outline in [the manual][simpleloginmanual]. First up, add a number of plugins to the application (in lib/Jacquard/

use Catalyst qw/

Create a default View class by running:

./script/ view TT TT

Then create the Catalyst Model class that will wrap Jacquard::Model::KiokuDB:

package Jacquard::Web::Model::KiokuDB;
use Moose;

use Jacquard::Model::KiokuDB;

BEGIN { extends qw(Catalyst::Model::KiokuDB) }

has '+model_args'  => ( default => sub { { extra_args => { create => 1 }}});
has '+model_class' => ( default => 'Jacquard::Model::KiokuDB' );


We also need to add the configuration for these plugins to the application config file:

name: Jacquard::Web
  dsn: dbi:SQLite:dbname=db/jacquard.db
      class: Password
      password_type: self_check
      class: Model::KiokuDB
      model_name: kiokudb

Finally, we can add a method requiring authentication to the root Controller (which is at lib/Jacquard/Web/Controller/

sub hello_user :Local :Does('NeedsLogin') {
  my( $self , $c ) = @_;

  my $name = $c->user->id;

  $c->response->body( "

Hello, $name!

" ); }

(Don't forget that you need to change the parent class of the controller as well:

BEGIN { extends 'Catalyst::Controller::ActionRole' }

If things aren't working, make sure you didn't forget this.)

With all this in place, you should be able to start up the application, by either running ./script/ or, if you want to get all Plack-y and modern, plackup jacquard_web.psgi, and then browse to the URL the server reports it's running on. You should see the Catalyst welcome page at that point. Add '/hello_user' to the end of the URL, and you should get prompted for a username and password. Assuming you created an account using the helper script from the [last installment][lastinstallment], you should be able to give those same values and see a page that says 'Hello' and your test account username.

Now, are we done? Not quite, as we don't have any tests of the authentication code! The following goes in t/lib/Test/Jacquard/Web/Controller/

package Test::Jacquard::Web::Controller::Root;
use parent 'Test::BASE';

use strict; use warnings;

use Test::Most; use Test::WWW::Mechanize::Catalyst;

sub fixtures :Tests(startup) { my $test = shift;

# load test config $ENV{CATALYST_CONFIG_LOCAL_SUFFIX} = 'test';

$test->{mech} = Test::WWW::Mechanize::Catalyst->new( catalyst_app => 'Jacquard::Web' ); }

sub auth_test :Tests() { my $test = shift; my $mech = $test->{mech};

$mech->get_ok( '/' , 'basic request works' ); is( $mech->uri->path , '/' , 'at top page' );

$mech->get_ok( '/hello_user' , 'request hello_user' ); is( $mech->uri->path , '/login' , 'redirect to login' );

$mech->submit_form_ok({ form_id => 'login_form' , fields => { username => 'test_user' , password => 'test_password' , } , button => 'submit' , } , 'login' );

is( $mech->uri->path , '/hello_user' , 'redirect to /hello_user' ); $mech->text_contains( 'Hello, test_user!' , 'see expected greeting' );

$mech->get_ok( '/' , 'basic request works' ); is( $mech->uri->path , '/' , 'at home page' );

$mech->get_ok( '/hello_user' , 'request hello_user' ); is( $mech->uri->path , '/hello_user' , 'go directly to hello_user' ); $mech->text_contains( 'Hello, test_user!' , 'still see expected greeting' );

$mech->get_ok( '/logout' ); is( $mech->uri->path , '/' , 'back at home page' );

$mech->get_ok( '/hello_user' , 'request hello_user' ); is( $mech->uri->path , '/login' , 'redirect to login' ); }

read more

Tags: catalyst , jacquard , kioku , perl