Just Do It

Have you ever thought about that? I haven’t really, until recently. It’s a nice, succinct, sort of catch slogan, but if you really think about it; what does it mean? Does it mean the same thing to Nike now as it did when the stumbled upon it in 1988? What does it mean to you?

For me it means getting out of my head, and getting into action.

For Nike, I think the intent was: Just get out there! Once you’re out there, you’ll probably want some of our shoes, but you don’t need our permission, Just Do It.

I’ve made more toy projects in the past 6 months than I have in the previous two years. Incidentally, I’ve had more fun writing code and learning in the past 6 months than I have in a few years.

I’m so tired of hearing about how you’re going to start doing something tomorrow or next week. Please start doing it now!

This doesn’t really have anything to do with writing code. It has to do with being intentional about the things you do. Learn how to knit, make a robot, be a better spouse, go to church more often.

No excuses. No explanations.

Tony Dungy

Go; DO.

Weapon of Choice: My Hands

My hands are the most versatile weapon I’ve got.

As a craftsman, my tools and weapons are extensions of my hands.

When I need to slice text, I reach for vim. There are still a few rough edges there, I’m starting to notice some wear lines near the features my hands invoke often.

When I need to do some general scripting or automation, I pick up a ruby, and some other gems to go along with it. This ruby is like a diamond, it never dulls, but it’s made a nice little indentations into my hands.

When I need to explain something complex, I often explain with my hands, as well as draw a picture.

A couple years ago, Craftsman (the tool brand) launched a campaign whose slogan was simply:

Trust. In Your Hands.

I love this slogan, and think about it quite often.

Alot of the time, I can just trust my hands to do the right thing. Once I’ve got the idea for a design or implementation in my head, sometimes I just need to get out of the way and let my hands work.

My hands are two things, as a craftsman, that I cannot live without.

Over/Under: Engineering

Over/Under: Engineering

It works but…

It follows design practices closer if we did it this other way.

or

It’ll make things easier when we do this other feature later.

or

But we shouldn’t take time to refactor, because this is just a prototype.

I hear these all the time (usually coming out of my own mouth). Sometimes I agree, sometimes I don’t, and yeah, context is king, but I usually struggle to even get a grasp on why I want to be ‘pure’ sometimes, and ‘quick-n-dirty’ others.

How do you decide how much is enough?

On my current project we’re constantly trying to find ‘good enough’. It’s conscious, and we think about it every day.

The problem we run into, however, is we don’t go back and revisit those decisions to see if we need to change our mind.

Finding harmony here seems (IMO), to be finding the right balance of KISS, YAGNI, and the last responsible moment.

get better

I do not aim with my hand; he who aims with his hand has forgotten the face of his father. I aim with my eye.

I do not shoot with my hand; he who shoots with his hand has forgotten the face of his father. I shoot with my mind.

I do not kill with my gun; he who kills with his gun has forgotten the face of his father. I kill with my heart.” – Stephen King, The Gunslinger

the face of my father

My dad is a master craftsman, and he taught me and my brother to be the same. Our crafts are vastly different, but the conversations we share about our workplaces are strikingly similar.

Every day, we learned the value of hard work, and putting care and heart into those works.

When I first came to software, I could sling some code together and it would work part of the time.

I was pretty happy with myself. This isn’t so hard. I’m throwing PHP around inside of notepad. I’m at the top of my game.

I had forgotten the face of my father. I didn’t know what else was out there, and I wasn’t looking.

remembering

When I got my first real software job, I got paired up with this guy across the hall. He helped me figure out these languages that were new to me. He introduced me to software engineering concepts like quality, testing, unit testing, OO design. He introduced me to new classes of tools, and how to build my own. He introduced to me the concept of putting hard work into my code, and caring about the work I was creating.

He reminded me of the lessons I had learned before, years before.

So what is it that keeps making me want to get better?

I’m a journeyman with a long road ahead of me until mastery. One of these days, I’d like to be able to wield my tools with the same fluidity and familiarity as my dad does with his tools.

The way I’ve found to get further along that road, is to do what I do. Learn, teach, re-evaluate, work hard, care, and craft. Do all of those things from the heart, not because someone, or some scoring chart thinks I should.

Where to start

I’d start here, or here. Also, I’d listen to Merlin a little.

The Applebees of Software Development

Meh

Don’t get me wrong, I like Applebees every now and again, but by in large, meh.

I’ll NEVER order a steak there, nor riblets (whatever that is).

The problem is, they do everything okay. Rarely do I find something there that is amazing.

From Meh, to Amazing

So, if you’re an Applebee’s how do you get out of the rut?

The way I see it, there are 3 ways out.

  • Stop being a [whatever it is that you do], and start being a customer experience company. Leave the offering the same, but kick ass at customer experience. This alone will bring people back; but don’t pretend to have great products (probably still ought to at least have decent ones though).

  • Cut your offering in half, twice. Focus on making what’s left amazing. Keep doing that.

  • Pivot. Re-invent yourself and your product/service offerings completely.

These all get you out of what appears to be an extremely profitable market (in Applebee’s case), and into a new one. Why was it that we wanted to leave in the first place?

We’re In A Rut?

If you’re happy with where you are, you’re shipping regularly, you’re profitable to your stakeholders, don’t get out! The hard part is realizing where you are is where you want to be, AND consciously staying on that path because you want to. This is equally as hard as any of the other three.

This, however, is not a free pass. You need to regularly introspect and figure out objectively (and subjectively) if you’re on the path you want to be on.

Go, find your amazing, and be it.

Code Reviews Are Great Unless...

… You’re Doing Them Wrong.

I hear this all the time (usually when I’m starting a new project)… but I never get a feel for what right/wrong means from the person that says it (and I’m usually a little too sheepish to ask what they mean).

It ain’t all about the bugs

It’s easy for me to have the wrong focus if I don’t remember why I’m doing the code review.

If I’m doing the code review because the PM tells me too, I’m probably going to be an asshole to whoever I’m doing the code review for.

If I’m doing the code review because I want to have a positive impact, it’s going to be better for me, and the reviewee.

My goals during a code review are something like the following:

  • Consistency
  • Collective Ownership
  • Distributed Learning
  • Camaraderie
  • Maintainable Code
  • High Quality
  • Valuable Software

So what does it mean to do code reviews correctly?

Here’s a few of the things I think it means to do a code review correctly.

  • Doing it right means small chunks.
  • Doing it right means looking for bugs.
  • Doing it right means looking for broken windows.
  • Doing it right means learning.
  • Doing it right means teaching.
  • Doing it right means giving positive reinforcement.
  • Doing it right means being constructive.
  • Doing it right means adding value.
  • Doing it right means having opinions.
  • Doing it right means letting go of those opinions.
  • Doing it right means being curious.
  • Doing it right means being ruthless.
  • Doing it right means being courteous.
  • Doing it right means being forgiving.
  • Doing it right means being timely.
  • Doing it right means being right.
  • Doing it right means being wrong.

Huh?

Most of those are directly contradictory, but I think they all apply.

For me, it’s a different balancing act every time I do a code review to make sure I’m meeting all the goals from above.

Is it hard to do well? Yes.

Is it worth it? Absolutely.

Bootstrapping Ruby/Pik for use in Git Bash in Windows

Every time I set up a new windows environment, I always have to go through the pik/ruby dance, and sometimes it’s difficult to get just right. Here’s my current preference:

Install Ruby 187 with the installer [http://rubyinstaller.org/downloads/]

Install Ruby 192 with the installer (make sure you tell the installer to set the PATH to include this ruby) [http://rubyinstaller.org/downloads/]

Install Pik with the installer [https://github.com/vertiginous/pik/downloads]

Open up your git bash

Create a ~/.pik/.pikrc with these contents (if it doesn’t already exist… mine never already exists):

#!/bin/sh
pik_path=C:\\pik

function pik {
$pik_path/pik_runner.exe pik.sh $@
[[ -s $USERPROFILE/.pik/pik.sh ]] && source $USERPROFILE/.pik/pik.sh
unset GEM_HOME
unset GEM_PATH
}

Run this at your bash prompt

[[ -s $USERPROFILE/.pik/.pikrc ]] && source $USERPROFILE/.pik/.pikrc

Optionally also put that line in your bashrc or wherever you put those types of things. If you’re looking for a good way to manage your dotfiles, I’ve forked spraints' version of a dotfiles manager here, that I like to use. It works on *nix and windows.

Close your git bash, open a new one, and pik away.

Ruby Named Parameters (with defaults)

So I was writing an internal testing DSL in ruby the other day, and decided it’d be nice for the folks writing the test scripts to be able to use named parameters as it would make the test scripts far more descriptive.

# not-named params
load_data 20, 50

# named params
load_data :num_users => 20, :num_items_per_user => 50

I think you can see for yourself which one is more readable. I ended up writing a small module (at the end of this post) that allows you to create methods with named parameters, and with default values for each, as well as accepting your parameters that aren’t named (though you shan’t mix the two).

Defining your methods

After including the module, you can create your methods like this:

def_named :method_name, :p_1, {:p_2 => 'p2 default'} do |p_1, p_2|
  puts p_1
  puts p_2
end

Important notes:

  • If you plan on using this without named params, you don’t get defaults
  • The order you define the parameter names is the order of the parameters if you’re not using named params (i.e. in the above example, ‘p_1’ would be the first parameter passed to the block for your method).
  • The block parameters don’t necessarily have to be named the same as the keys you defined for your named params (though, it’d make sense to make them be the same, for your own sanity).

So, for the load_data example above:

def_named :load_data, :num_users, :num_items_per_user do |num_users, num_items_per_user|
  #load the data
end

#called with named params
load_data :num_users => 20, :num_items_per_user => 50

#called without names
load_data 20, 50

#called with named params (keys/names out of order is OK)
load_data :num_items_per_user => 50, :num_users => 20

The module

I’m certain I haven’t invented anything new here, but it was a decent exercise in metaprogramming for ruby (for me), so it was fun. I haven’t exhaustively tested this to make sure it doesn’t break down if you abuse it, but I don’t plan on abusing it.

Here it is:

module NamedParams
  def def_named(method_name, *keys, &block)
    NamedParams.def_named_method(method_name, *keys, &block)
  end

  private

  def self.def_named_method(method_name, *keys, &block)
    define_method(method_name) do |*args|
      parsed_args = NamedParams.get_splatted_or_keyed_args(args, *keys)
      block.call(*parsed_args)
    end
  end

  def self.get_splatted_or_keyed_args(args, *keys)
    return_args = []
    if (args.size == 0) || (args.first.is_a? Hash)
      keys.each{|k| return_args << NamedParams.get_default_or_arg(k, args.first || {})}
    else
      args.each{|a| return_args << a}
    end
    return_args
  end

  def self.get_default_or_arg(key, args)
    key_name = NamedParams.get_key_name(key)

    if (key.is_a? Hash) && !(args.has_key? key_name)
      key[key_name]
    else
      args[key_name]
    end
  end

  def self.get_key_name(key)
    key_name = (key.is_a? Hash) ? key.keys.first : key
  end
end

I would be interested on any feedback if you have anything constructive. Enjoy.

Terminal Math

So, lately, I’ve been needing to do little snippets of math and use them as parameters to curl requests, or just know what the result is in general.

Simple Math

This’ll add 1 and 2 together for you… pretty sweet.

echo "(1+2)" | bc -l

Date Math

The one that bothered me the most was one that was based on the current date. Actually, determining the number of milliseconds since the epoch (Jan 1, 1970), 10 hours ago.

Here’s the gem that saved me:

date +\(%s000-\(10*60*60*1000\)\) | bc -l

Explained: Everything before the pipe is using the “date” command to output a string that contained an expression to computer the time in milliseconds since the epoch. %s outputs the number of seconds, based on UTC, and I’m in Indiana, so I had to account for 5 hours difference. The other 5 hours is because I’m dealing with a server in Germany, which is 5 hours different than here.

A sample output from the stuff before the pipe would be:

$ date +\(%s000-\(10*60*60*1000\)\)

(1296567305000-(12*60*60*1000))

Enjoy the ice.

curl is amazing

Need to do a quick test of a web api, but don’t want to write code to check it out? Just use curl.

curl --help

That’ll get you started, but there are tons of options, so here’s some I like to use alot.

Form data

curl --form username=jon --form [url]

Basic auth

curl --basic --user username:password [url]

Posting a file as if you’re uploading a file (note the @ on the front of filename.xml, that tells it to use the file in that location)

curl --form upload.xml=@filename.xml [url]

Posting a file as if it’s the actual payload

curl --data @filename.txt [url]

Including a custom header

curl --header "headername: headervalue" [url]