Perl Switches 101
The backstory to this post is a little weird in that it involves rjbs much more than usual. A couple weeks ago I was playing D&D with rjbs and Abigail, and before the game got started somehow we ended up talking about Masterminds of Programming. The book is pretty good so far, you should totally read it! Anyway, the book has a chapter on AWK and for some reason I mentioned to rjbs that I need to buckle down and learn AWK.Posted Fri, Aug 16, 2013
Event Loops: Useful After All
I’ve had a series of blog posts referring to event loops; the final message ended up being something like YAGNI. Well, I am eating my hat in this blog post; I have seen the light, I am drinking the kool-aide, I am stockpiling weapons… er, how about I just give some details! Tech Aside: IO::Async I have done some research for a blog post comparing AnyEvent, POE, and IO::Async. This is not that blog post, but in researching that post I came to a conclusion.Posted Sat, Jul 27, 2013
Install and Configure the MS ODBC Driver on Debian
This page is only here for historical interest; the updated guide is here. This was originally written by my coworker Wes Malone and adapted to Ubuntu by my other coworker Geoff Darling. Basically it should get you up and running with Microsoft’s official ODBC driver in Debian based Linuxes. Enjoy! The Microsoft ODBC Driver (AKA the SQL Server Native Client) is Microsoft’s official ODBC driver for SQL Server. Since 2011 Microsoft has provided binary builds officially supported on Redhat Enterprise Linux.Posted Fri, Jul 5, 2013
I made my own keyboard!
Check out the pictures at flickrPosted Tue, Jun 11, 2013
l2type nub
Today I found out I have tennis elbow from the stupid way I type. I’m writing this blog so you’ll all not develop my stupid bad habit. Basically I configured awesomewm to use the alt key as the modifier instead of the windows key, because I learned to use the alt key in xmonad… Now, I don’t know about you guys, but all of they keys that share a row with the spacebar are hard to press in general and for some reason my dumb hands decided the only way to press alt was to curl my thumbs inward and press that way.Posted Tue, May 28, 2013
Some Kickstarters I Have My Eye On
Some fun kickstarters I’ve got my eye on: Blasphemous Cocktails Cocktails inspired by HP Lovecraft stories and others. It is already funded and I am definitely getting it. The Wine Curmudgeons Guide to Cheap Wine The title says it all. Assuming this gets funded I plan on getting it. I love when people don’t have a minimum $20 a bottle to like a bottle of wine. The Whole Story: Winter 2013 I already “got” this one.Posted Sun, Jan 27, 2013
The Pomodoro Technique
A couple of weeks ago I was frustrated at my own lack of productivity. I decided to purchase Pomodoro Technique Illustrated: The Easy Way to Do More in Less Time. I had actually already attempted the Pomodoro Technique based on what I read on the internet, but it never seemed to work for me. This short, easy read has made a noticeable difference in my productivity. But the book is not the point of this post, The Method is.Posted Fri, Jan 25, 2013
Announcing Apache::BalancerManager
At work I use Apache as it’s the best thing out there for perl on windows. One of the features of Apache when you are using it as a load balancer is it’s UI for controlling the Balancer Manager. One of my coworkers remarked that it would be nice to have an API for that so that when we restart workers we could tell the balancer manager first so that the worker would not get dispatched to until it finished restarting.Posted Fri, Jan 11, 2013
Abstraction Levels
One of the decisions we developers must make when writing our modules is at what level to abstract our code. I, for instance, write a lot of DBIx::Class components, which is, for the purposes of this discussion, about the same as a role (and I will just use the term role for the rest of the article.) For a long time that was my standard modus operandi, but I’ve started to think that that is a bad default and that I need to consider more carefully what to use.Posted Sat, Jan 5, 2013
Go See My DBIx::Class Advent Article!
woohoo! Again, I’ll probably reblog this in January.Posted Fri, Dec 21, 2012
Go See My Advent Article!
Merry Christmas! (I’ll reblog it next month probably.)Posted Thu, Dec 13, 2012
ssh tips
As a developer, I use ssh all the time. When connecting to the various servers and even other computers in my house, ssh is my go to. Most writable git servers use ssh. A newish Perl module by mst (Object::Remote) uses ssh for communication. There are a number of tricks you can use to make using ssh as hassle free as possible. I’ll share these tips here. ~/.ssh/config First and foremost is getting intimate with ~/.Posted Wed, Nov 14, 2012
Announcing DBIx::Class::MaterializedPath
Have you ever wanted to store trees in your database? How about store them and avoid melting your database server at retrieval time? Did you want to use materialized path and were sad when there were no quality modules to do it with DBIx:Class? DBIx::Class::MaterializedPath I recently had a need for storing tree-ish data in a table and I got it working with extended relationships and a helper or two.Posted Mon, Sep 10, 2012
Hash your passwords!
More than two years ago I blogged about how to correctly store passwords. Recently a number of high profile websites have had their password storage compromised. The storage method I blogged about two years ago is still hugely better than what LinkedIn (SHA1, no salt) and I think Gawker had. If you aren’t already securely storing passwords, this post should get you going on a conversion. First off, here’s a DBICDH/DBICM compatible conversion scriptPosted Mon, Sep 3, 2012
Zero DM RPG's
My weekly table top rpg is Changeling, which is one of the World of Darkness templates. This past week some stuff went on sale on DriveThruRPG so I picked up a few things that I’d wanted to look at for a while. For our game I’m the DM or GM or Storyteller or whatever you want to call that. It’s not because I’m overly creative or even wanted to, it’s because I wanted to play and no one else seemed willing to do it.Posted Sat, Jul 28, 2012
awesomewm
I’ve had a long, sordid relationship with window managers. When I really started with my first computer it was Windows 98 and I somehow decided to put Litestep on it. I remember switching workspaces was often crashy and I pined for something less hacky. Eventually I installed some form of linux. Because Litestep was inspired by AfterStep I knew that’s what I really wanted. But I was wrong. I may have wanted that if I were already a console user, but I was weening myself out of windows.Posted Wed, Jul 4, 2012
Web::Machine + Web::Simple is awesome
I really like “REST,” which the pedantic of you will realize is really just using more than just basic HTTP. I’ve gotten used to a handy REST-y pattern with Catalyst, which, though verbose, is pretty neat: use Catalyst::Controller::Accessors; cat_has account => ( is => 'ro', namespace => 'MyApp::Controller::Accounts', slot => 'thing', ); cat_has $_ => ( is => 'rw' ) for qw(rs thing id); sub base : Chained('/accounts/item') PathPart('contacts') CaptureArgs(0) { my ($self, $c) = @_; $self->rs($c, $self->account($c)->contacts) } sub item : Chained('base') PathPart('') CaptureArgs(1) { my ($self, $c, $id) = @_; $self->id($c, $id); $self->thing($c, $self->rs($c)->find($id)); } sub contacts :Chained('base') PathPart('') Args(0) ActionClass('REST') {} sub contacts_POST { my ($self, $c) = @_; my $params = $c->request->data; my $foo = $self->rs($c)->create($params); $c->stash->{rest} = { success => 1, data => $foo }; } sub contacts_GET { my ($self, $c) = @_; $c->stash->{rest} = $self->ext_paginate( $self->search($c, $self->paginate($c, $self->sort($c, $self->rs($c)) ) ) ); } sub contact :Chained('item') PathPart('') Args(0) ActionClass('REST') {} sub contact_GET { my ($self, $c) = @_; $c->stash->{rest} = { success => 1, data => $self->thing($c), }; } sub contact_PUT { my ($self, $c) = @_; my $foo = $self->thing($c); my $params = $c->request->data; $foo->update($params); $c->stash->{rest} = { success => 1, data => $foo }; } sub contact_DELETE { my ($self, $c) = @_; $self->rs($c)->search({ id => $self->id($c) })->delete; $c->stash->{rest} = { success => 1 }; } That’s cool.Posted Wed, Jun 27, 2012
Announcing Catalyst::Action::FromPSGI
At YAPC this year I spoke with Stevan Little about his new module, Web::Machine. He mentioned that ultimately he wanted to figure out how to shim it into Catalyst. mst actually implemented something like that exactly a month ago, and I actually want to use it to make little redistributable apps that are the backend implementations of the gadgets for our dashboards at work. So I took Matt’s code and made a module!Posted Mon, Jun 25, 2012
DBIx::Class::DeploymentHandler Backup based workflow
In my last post I wrote about how to make a backup for each migration you run. That’s a great trick that opens the door for this next tip. I’ve never really trusted or been comfortable with downgrade scripts. If your downgrade script truly is the reverse of your upgrade script it’s almost inevitable that your upgrade script will be archiving changed data so that the downgrade script can undo said change.Posted Fri, Jun 8, 2012
DBIx::Class::DeploymentHandler + Backups
Given that DBIx::Class::DeploymentHandler is a widely misunderstood and confusing module to the point that a friend of mine wrote DBIx::Class::Migration a module to wrap it up more nicely, I’ve decided that some blog posts showcasing how I use DBICDH are in order. If you don’t already know, DBICDH was written by me, and designed my mst, myself, ribasushi, and Rob Kinyon. The latter two claim to barely remember our discussions early on, but I’ll credit them as having helped me design what I made.Posted Wed, Jun 6, 2012
Introducing DBIx::Class::Helper::Schema::LintContents
Surprisingly recently we decided to actually clean up our database in my current project at work and add primary, unique, and foreign key constraints. For most projects that’s really not that hard, but because our project is a turn key server and it’s deployed on hundreds of customers’ sites we can’t just fire up a database shell and fix any broken constraints before we deploy them. So I made a tool that would quickly and correctly delete all but one of the duplicates of primary and unique constraints, and would delete the dangling children of broken foreign keys.Posted Mon, Jun 4, 2012
Introducing DBIx::Class::Helper::ResultSet::SearchOr
Arguably the most important design decision that mst made when first writing DBIx::Class was the choice to make chainable resultsets. A fundamental part of that design is that when you chain off of a resultset you should always get a subset of what you started with. This is important because it’s what makes searching from a user object or similarly using DBIx::Class::Schema::RestrictWithObject work in a safe manner. Most everyone should know at this point that the best way to use DBIx::Class it to make various ResultSet methods that return named subsets of data.Posted Fri, Jun 1, 2012
Introducing DBIx::Class::Helper::ResultSet::CorrelateRelationship
Recently at work we ran into an issue where a report was timing out. At first I thought it was because the server was overloaded, or the clients that were connecting to it were doing so improperly. Both of those things were true, but they weren’t the cause of the problem. The problem was this: sub TO_JSON { my $self = shift; return { %{$self->next::method}, failed_location_tests => $self->test_computer_links->failed->count, location_tests => $self->test_computer_links->count, device_tests => $self->test_device_links->count, total_pcs => $self->all_computers->count, total_pcs_failed => $self->failed_computers->count, total_pcs_succeeded => $self->succeeded_computers->count, total_pcs_untested => $self->untested_computers->count, } } So to be clear, with our standard pagination of 25 rows per grid, this was doing the initial query to get the data, and then SEVEN additional queries per row.Posted Wed, May 30, 2012
Introducing JavaScript::Dependency::Manager
Nearly a year ago my grandfather passed away. He had some form of dementia for a long time and I personally wasn’t hit very hard by it, but as is the custom I went home to visit my family when it happened. On the drive down I listened to Childhood’s End and Rendezvous with Rama. At work I’d been tackling the problem of users with custom dashboards and possibly even the ability to have gadgets that we sell separately.Posted Mon, May 28, 2012
Introducing DBIx::Class::UnicornLogger
More than a 1.5 years ago we added color coded, formatted SQL output to DBIx::Class. Since then I’ve tried adding various configurable logging facilities to the core, but I haven’t had much luck getting the API for that whipped into shape. So I’m giving up on getting it into the core for now and releasing it separately. It’s pretty rough around the edges, but it’s a logger, so it’s not like you could depend on it working a certain way and get into any kind of trouble with it (yet.Posted Fri, May 25, 2012
Introducing Catalyst::ActionRole::DetachOnDie
In my last post I introduced Catalyst::Controller::Accessors, which is mostly aimed at users who do a lot of chaining. This module is similarly targeted for chaining users. Anyone who has used chaining for more than a few weeks will know that exceptions in chains are stupid; an exception will not stop the chain, but merely end the current part of the chain, add to $c->errors, and run the next part of the chain.Posted Wed, May 23, 2012
Introducing Catalyst::Controller::Accessors
Ugh, I first released this eight months ago, but I fell off the blogging wagon pretty badly. It’s so hard to write when I could be writing code, docs, and tests! So anyway, I’m trying to get caught up on the eight announcements that need to be made as well as a few DBIx::Class::DeploymentHandler related PSA’s. I’ll schedule them to get auto posted with at least a few days between so I don’t melt your feed reader or bore you too much.Posted Mon, May 21, 2012
Using search.cpan.org AND metacpan
I appreciate the effort and openness of metacpan, but their search is still pretty bad. To be clear, compare the results of the search for DBIx:Class::Source on SCO and metacpan. That’s why I made the following greasemonkey/dotjs script: $('a').each(function(i,x){ var obj = $(this); var href = obj.attr('href'); var re = new RegExp('^/~([^/]+)/(.*)$'); this.href = href.replace(re, 'https://metacpan.org/module/$1/$2'); }) Put this in ~/.js/search.cpan.org.js to install it with dotjs. Feel free to extend it to work for more than just modules.Posted Wed, May 16, 2012
The Rise and Fall of Event Loops (in one very small place of my code)
In the spirit of one of my other posts I’ve decided to chronicle my path with at least a couple event loops. More than eighteen months ago I documented my decision to start using an event loop as it would handle things I may not have considered, the example mentioned specifically in that post being exceptions. Things went well! I used the code I documented in that post for a long time with no issues until recently.Posted Wed, Mar 7, 2012
Perl Event Loop
I have some extremely basic code using AnyEvent but I recently found out that I was doing it wrong. That is, the entire reason I am using an event loop is to catch errors, log them, and keep going. That’s one of the great benefits that Catalyst gives me; I override one thing and I get universal error logging. The problem is that AnyEvent specifically does not handle this use case.Posted Sun, Mar 4, 2012
Using Catalyst::Plugin::Authentication with an old setup
Recently I took it upon myself to make Catalyst::Plugin::Authentication know users had logged in after users had logged in in a completely non-Catalyst part of our app. After LOTS of frustration, code spelunking, and bugging a couple people in #catalyst (hobbs and t0m) I got it working. Basically what I did was have the session plugin look at a different cookie and load information from our own strange brew of session table.Posted Wed, Jan 18, 2012
Cloning Objects in Perl
Recently I needed to do some deep cloning of some objects at work. I think I ended up looking at all of the major ways to do it, and I figure I might as well discuss them here. What is deep cloning? Nearly everyone should be able to answer this, but it doesn’t hurt to define it anyway. Deep cloning means you clone other things the current object is related to, recursively.Posted Tue, Sep 20, 2011
Shortcut Constructor Method & Conversion
I left my book and notes at work yesterday, hence the late post. Shortcut Constructor Method What is the external interface for creating a new object when a Constructor Method is too wordy? Sometimes creating an object is exorbitantly wordy. The example that the author gives (in javascript) is the following: var p = new Point({ x: 1, y: 2 }) Add methods to a lower level object that can construct your objects.Posted Wed, Sep 7, 2011
Creating a pseudo attribute with DBIx::Class
I’m surprised I haven’t actually blogged this before. I had to do it recently for the first time in a long time and I figured I’d share the secret sauce. At work we just added a complete permission system on top of our existing user system, but we didn’t want to make the UI as flexible as the underlying code. We ended up making a single role (which has all permissions) called “Full Control”.Posted Sun, Sep 4, 2011
Smalltalk Best Practice Patterns - Constructor Parameter Method
How do you set instance variables from a constructor method? The fundamental issue here is that often validation is bypassed at construction time, for whatever reason. So one’s accessor may look something like this: sub x { my $self = shift; if ($self->constructing) { if (exists $_[0]) { $self->{x} = $_[0]; } else { return $self->{x} } } else { if (exists $_[0]) { die 'too high!' if $_[0] > 100; die 'too low!Posted Sat, Sep 3, 2011
Smalltalk Best Practice Patterns: Constructor Method
Sadly reading is going slower than expected due to being so busy with various things in life. Oh well, just a single pattern today. Constructor Method How do you represent instantiation? In addition to a vanilla constructor, add methods for common cases to instantiate typical objects. For strange cases allow the use of accessors. Using Perl (with Moose) an example might be: package Point; use Moose; has x => (is => 'ro'); has y => (is => 'ro'); sub r_theta { my ($class, $r, $theta) = @_; $class->new( x => $r * cos($theta), y => $r * sin($theta), ); } 1; So now both of the following work:Posted Thu, Sep 1, 2011
Smalltalk Best Practice Patterns - Chapter 3 - Behavior - Methods
Today I had to spend time taking care of passport stuff for my upcoming honeymoon, so I only got to read a handful of pages. I’ll post my notes nonetheless. Methods are more important that state because, correctly factored, methods paper over any changes in state over time. Most of us who took OO classes in college had this hammered into our brains :-) Methods should be written to get something done, but should also be written to communicate with the reader.Posted Thu, Sep 1, 2011
Smalltalk Best Practice Patterns, Chapters 1 and 2
For work I decided I’d start reading some technical books, taking notes, and then trying to reiterate what I’ve learned. Yesterday I read the Preface and Chapter 1 and today I read Chapter 2, but sadly it’s all still introductory. I might as well discuss what I’ve read nonetheless. First though, I should say that I am reading the book because Thomas Doran of Catalyst development recommended it, and it clearly applies to Perl with Moose.Posted Tue, Aug 30, 2011
Weekly Status Report 4
This week I finished the following three git conversions: Catalyst-Authentication-Store-DBIx-Class Catalyst-Authentication-Credential-FBConnect Catalyst-Authentication-Credential-OAuth And I started on the following four git conversions (I think they are ready but I want t0m to sign off on them) : Task-Catalyst Catalyst-Plugin-Authentication HTTP-Request-AsCGI Catalyst-Action-RenderViewPosted Mon, Aug 29, 2011
Stop accidentally committing all with git
One of the things that annoys me a lot when using git is if I go through a lot of work to stage some changes, probably using git add -p to stage parts of files, and then from muscle memory I type git ci -am 'lolol I dummy'. If you didn’t know the -a says commit everything, so then of my painstaking staging is gone. Well, on Thursday I finally fixed this problem.Posted Mon, Aug 29, 2011
Refactoring Dispatch Tables into Objects
One of the cool ways of doing things in Perl is to use a dispatch table. The most obvious dispatch table is a hash of subroutines: my $x; my $table = { GET => sub { return $x }, PUT => sub { $x = $_[0] }, }; sub dispatch { my ($method, $data) = @_; if (my $fn = $table->{$method}) { $fn->($data) } else { die 'METHOD NOT ALLOWED!' } } This is a pretty cool thing to be able to do easily.Posted Thu, Aug 25, 2011
New Stuff in Catalyst::ActionRole::PseudoCache 1.000001
I’m excited to announce a new version of Catalyst::ActionRole::PseudoCache. New in the current release of Catalyst::ActionRole::PseudoCache is that it can now use Catalyst::Plugin::Cache as the underlying cache mechanism. The main reason was that the existing architecture didn’t work for multiple servers, which is how our system works. Plus this is just better overall. In the long term I will be removing the old “Pseudo” cache. It might be a good idea to make a separate package with a better name at some point, but that will be for the next release.Posted Tue, Aug 23, 2011
Weekly Status Report 3
I don’t feel great about this past week, but I was really busy with wedding planning stuff. I barely made either of my two main goals (2 blog posts and 2 patches/releases a week.) Last week I: Released a new version of Log::Contextual Released a new version of DBIx::Class::Helpers I have high hopes for the coming week, that I can get more important releases and more interesting blog posts written.Posted Mon, Aug 22, 2011
Using Cygwin instead of msysGit
Our main product at work is a Windows product. The reasons are complicated, but the main reason is that that is what our customers seem to want. What this means is that I do some of my development on a virtual machine. For a long time I was just using msysGit. msysGit goes a long way; you have a real bash console, a bunch of standard unix commands, and very good windows integration.Posted Mon, Aug 22, 2011
Git aliases for your life
I only use a handful of git aliases, but the ones I do I really like. First off, the basic ones: [alias] ci = commit co = checkout st = status br = branch Also, another handy tip, as pointed out by a commenter is aliasing g to git (alias g=git) so that after you do the above instead of git ci you can merely do g ci. Neat.Posted Wed, Aug 17, 2011
Weekly Status Report 2
This week I: Released a new version of Class::C3::Componentised Released a new version of DBIx::Class::CandyPosted Tue, Aug 16, 2011
You should be using git grep
Usually when searching through files I use ack which is an awesome tool indeed. Unfortunately, though ack does indeed work on windows, using it on windows is a painful experience. The main two problems are that it’s slow and the color coding doesn’t work. I figured I’d try out git grep, with the hope that it might be marginally better. I try my best to at least be familiar with all the git commands, so this is one of those things I had been meaning to do anyway.Posted Sun, Aug 14, 2011
Powerful benchmarking with Perl and ab
One of my projects at work was to make an SMS (and voice actually) gateway. The gist is that instead of our customers each having an account with whatever text message company, they go through us. The benefit is that with a larger pool of users for the text messages users can have a lot more flexibility with how they use their messages. Most gateways sell you messages per month, and we sell yearly messages.Posted Fri, Aug 12, 2011
New Stuff in Class::C3::Componentised 1.001000
I’m very excited to finally announce a feature that I’ve toyed with in Class::C3::Componentised for over a year now. New in the current release of Class::C3::Compontised is Class::C3::Componentised::ApplyHooks. The gist is that you can run code, or more importantly methods, against the class being injected into. I wouldn’t be surprised if few people reading this actually know what Class::C3::Componentised is actually used in; the answer is DBIx::Class. The upshot of this new feature is that you could write a component to add columns or relationships much more nicely than before.Posted Wed, Aug 10, 2011
Weekly Status Report 1
This week I sent a small patch (along with a lot of discussion) to Exodist for Exporter::Declare released an awesome new version of Log::ContextualPosted Mon, Aug 8, 2011