Goodbye, Brooklyn. Hello, Portland!

| Comments

Two and a half years ago, Meaghin and I moved from Washington, DC to Brooklyn. Our move came as a bit of a shock to our family and friends – partly because of its suddenness, and also because of its proximity to our marriage. The move to Brooklyn was not motivated by a job opportunity or anything similar; instead, we had started feeling constrained by DC after five years of living there, and couldn’t imagine a more challenging and exciting place to live than New York (and Brooklyn in particular). A week after getting married, we made the decision to move, and three weeks after that, we found ourselves surrounded by boxes in an apartment overlooking the East River and Manhattan.

The first few months of living in New York definitely delivered on the “challenging” part of our expectations; not a day went by that didn’t evoke memories of Seinfeld plot-lines. Crazy co-op boards? Difficult supers? Ridiculous encounters on the subway? More than one New York stereotype proved its roots in authenticity. But as we grew used to the city and its neighborhoods, learned how to quickly cut from one area to another, discovered which subway lines consistently failed, and realized that one should avoid 5th Ave and Times Square at all costs, the challenges started to dissipate and left only excitement. New York, in its intensity and genuine melting pot of cultures and backgrounds, presents an amazing opportunity for people to define themselves. What matters most to you, and why does it matter? In a city where practically any hobby or interest can be pursued, you’ve got to seriously prioritize your time, and that prioritization goes a long way towards identifying exactly who you are.

But for all the excitement and growth, I started to notice another development in myself: pernicious cynicism. While I had once dreamed of tackling big problems and making the world a better place, years of living in DC and New York made me view such ideas as hopelessly naive. The seeming intractability of so many daily problems, the realization that apparently important movements were actually driven by petty motivations; older, wiser me didn’t look at idealists with disdain, but rather with a wistful admiration of their blissful ignorance.

Then I spent time in Portland, OR.

It’s hard to describe the feeling of Portland. And I don’t mean the city portrayed on Portlandia – although that show is certainly accurate in its skewering. I have never been to a place where so many people devote themselves to mastering a craft, not just because of the rewards of the mastery, but because not mastering that craft is simply not an option. There’s an entrepreneurial spirit that pervades Portland, but it’s one that’s devoted to developing new ideas and contributing back to the community. Even this “return to community” is not the traditional “I’ve done well so I’m giving back” idea, but rather a networked entrepreneurship, a continuous exploration of “How can my idea involve the unique work of that awesome ?”

Mikeal Rogers, organizer of NodeConf, described Portland with admiration:

There are times and places, great cities, that are remembered much more
fondly than they were thought of at the time. Paris in the twenties when it
was home to Hemingway, Picaso and Fitzgerald. Or San Francisco in the 50s
when the beat generation migrated from New York to call it home. So
impressionable were those years that the echo fuels future, lesser,
generations for decades.

When you're in Portland, Oregon you can't help but think it might be such
a place and the time. For what it will be remembered I have no idea, but
everyone seems to be bursting with creativity and no one is content until
they have done more.

Spending time in Portland pierced the shell of cynicism that I’d developed, and rekindled my motivations to build something real and lasting, to improve my community. Portland provides the inspiration; New York has provided the confidence and skillset to do something about it.

So once again Meaghin and I find ourselves surrounded by boxes and preparing for a big move. In a month I’ll be a resident of Portland. I can’t wait to find out what the future will bring.

Why JavaScript on the Server Isn’t Such a Bad Idea

| Comments

Preaching the gospel of Node can be a tough job: how do you express your excitement for the technology without coming across as a fanboy? And how do you deal with people that view it as a cancer? I had to answer these questions when crafting a presentation last week introducting Node.js as part of a developer tech talk. Given the radically divergent opinions that Node has elicited, I wanted to address the FUD head on. I tried to focus on the gut reaction most people tend to have towards Node (“WHO would want to code their server in JS?!”), and I think the talk went fairly well. I’m embedding the slides here if anyone would like to take a look. Speakerdeck is a fantastic resource and I was happy to finally put it to use as a producer, instead of just a reader.

For even more insight into the developing world of “JavaScript everywhere”, check out this video from Joe McCann, principal architect of subPrint Interactive, on “End to End JavaScript”.

Welcome to 2012

| Comments

January’s been a long month; not in a bad sense, just sort of interminable. Looking through my links collection in notational velocity today, I found a good twenty plus from the last six weeks. I’ve culled them down a bit to the true standouts:

  • An Object is not (Always) a Hash — Great post from Guillermo Rauch about the perils of using Javascript Objects as Hashes. Definitely some tricky gotchas here that you may not have thought about.

  • Hot Node Reloading — Also from Guillermo, a solution to the annoying problem of continuously restarting your node app during development: Staying Up with Node.JS

  • Shedding Light on SPDY — If you haven’t been hearing a great deal about SPDY lately, you will be soon. SPDY, if you couldn’t tell from the name, serves as a next-generation protocol to speed up web communication. Nodejitsu posts a helpful introduction to SPDY.

  • Improving your Git Logs — Git log, out of the box, is so wordy that it proves fairly worthless. Check out Oli Studholme’s aliases for taming the git log beast.

  • Hack Learning — One of the key lessons I’ve learned as a developer is that getting good at something requires hours, and hours, and hours, and hours of work, and many of these hours will be exhausting displays of ignorance which you’ll want to quickly forget. The good news is that you can pick up nearly any skill with enough effort and time. Jack Kinsella provides a hack for cutting back on how many hours separate “terrible newb” from “fairly competent practitioner”. His Janki Method may sound like a get rich quick scheme, but it’s really just a simple approach to improving your effiency at learning. Maybe you can cut those 10,000 hours of practice to a more managable… 6,000.

A Year in Coffee

| Comments

Last year was the first that I dove deeply into the coffee world, turning what was previously an interest into a full-blown passion. While I had previously ground beans at home and brewed in a french press, I decided sometime in 2010 that I wanted to learn more. Going into 2011, I started brewing with an aeropress and chemex, upgraded my grinder to a Baratza Virtuoso, and furthered my coffee knowledge by reading God in a Cup and Uncommon Grounds. I began taking notes on my home brews and asking questions at coffee bars. And I bought lots of coffee. Lots and lots and lots of coffee.

Lots of coffee

Meaghin has more pictures and a full rundown of our 2011 coffee purchases, but I wanted to highlight a few bags in particular.

Coava and Wrecking Ball

Wrecking Ball Coffee Roasters is a new enterprise from Trish Rothgeb and Nick Cho; I was lucky enough to get one of the first bags they shipped this year. Their coffee presented a perfect example of what makes me love Ethiopian coffees, offering a pleasantly light body without being too acidic. I like to compare good east African coffees to pinot noir – almost all have a juiciness to them, but the best are balanced with strong bass notes. I loved Wrecking Ball’s fully biodegradable package. But beyond the coffee itself, I was happy to order from Wrecking Ball because of Nick Cho. Cho used to run the amazing Murky Coffee in Arlington, VA, which I visited very frequently when I lived in the DC area. Ironically, I didn’t drink much coffee at the time, having been exposed to some swill in college. But Murky is what enticed me to learn more: the intoxicating smell of freshly ground Counter Culture coffee, the precise movements of the baristas as they brewed espressos, the clear passion of everyone involved. Drinking the Wrecking Ball made me feel as if I were making up for the coffee I never enjoyed at Murky.

If Murky induced my coffee passion, Coava revealed the heights to which this passion could be taken. I drank Coava’s David Mancia from Honduras early in the year; later, I would visit Coava’s Portland shop in person. The David Mancia completely blew my mind. Even in my early days of home-brewing, I couldn’t screw this coffee up: chocalate, berries, an amazing finish, thick and juicy and succulent. I couldn’t wait to see how Coava’s shop measured up to the coffee they roasted, and found one of my favorite coffee shops in the country. I can’t wait to go back.

Coffee Collective

One of the highlights of 2011 was my trip to Copenhagen with Meaghin. Before the trip, I greatly anticipated experiencing Danish culture, perhaps most intrigued by their coffee culture. Almost everywhere we bought coffee in Copenhagen, we felt pleased with the product, but Coffee Collective is an entity unto itself. We visited their new location in Torvehallerne, a glorious outdoor food market, a few times, trying various coffee drinks on each visit; the Kieni from Nyeri, Kenya proved particularly delicious.

Two weeks into 2012 and as many bags brewed; I’m currently finishing up a great roast from Cafe Grumpy, from Finca La Coqueta in Columbia. I look forward to finding out what my favorites will be this year.

Better Support for Helpers in Vows-bdd

| Comments

This last week has been a particularly busy one, so I’ve been delayed in blogging, but I released v0.2 of vows-bdd to NPM a week ago. There’s two changes of note. The first is proper documentation for the library: you can see the docco documentation here. If you’re new to vows-bdd, or just want to learn more about how it’s working, the docs should provide all the answers you’re looking for.

The more important change relates to the testing syntax. In some conversations I had online with Graeme Foster, I realized that the vows-bdd syntax left some room for improvement. Specifically, the syntax introduced a potential for redundancy when creating labels for integration tests. While named functions could be used for test statements that were repeated, there wasn’t an easy to way to handle repeated labels.

In order to make the use of test helpers even easier with vows-bdd, I have adjusted the given/when/then/and syntax to allow for array arguments in addition to the previous arguments of label,test_function. It’s easiest to demonstrate the change with an example. One area of code that frequently is repeated is login code in integration tests. Here’s how I had my tests setup with vows-bdd before:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# a test snippet

  .given "I am an admin user", ->
    @user = Model.Factory.create "user", {role: 'admin'}
    @callback()
    return

  .when "I go to login", ->
    zombie.visit Server.path_for("/login"), @callback

  .when "I click login", (browser,status) ->
    browser.fill("email", "#{@user.email}")
           .fill("password", "#{@user.password}")
           .pressButton "Login", @callback

  .then "I should be on the admin index", (err,browser,status) ->
    Test.assert.shouldBeOn browser, "/admin"

# snippet from another test

  .given "I am an admin user", >
    @password = "foo"
    @user = Model.Factory.build( "user", password: @password, passwordConf: @password, role: "admin" )
    @user.save @callback

  .when "I am logged in", >
    user = @user
    cb = @callback
    pw = @password
    zombie.visit Server.path_for("/login"), (e,browser,status) >
      browser.fill "email", user.email
      browser.fill "password", pw
      browser.pressButton "Login", cb
    return

Even with the previous syntax, this code could be improved by creating a named login function that handles the duplicated code. And you could add a property to that function that provides a label. But I felt that the vows-bdd syntax should be improved to make this code repetition even easier. So the new [label,function] syntax looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# first test

  .scenario("'/admin' is accessible to logged in admin users")

  .when(I.login_as "an admin")

  .then "I should be on the admin index", (err,browser,status) ->
    Test.assert.shouldBeOn browser, "/admin"

# other test

  .scenario("Logging Out")

  .given(I.login_as "an admin")

  .when "I click logout", (browser,status) ->
    browser.pressButton "Logout", @callback

  .then "I should be redirected to the login page", (err,browser,status) ->
    #continues

The login_as function is included in a helper file:

1
2
3
4
5
6
7
8
9
10
11
exports.login_as = (type_of_user) ->
  label = "I login as #{type_of_user}"
  fixture = () ->
    cb = @callback
    @user = user = Model.Factory.create type_of_user.match(/a[n]? (\w+)/)[1]
    zombie.visit Server.path_for("/login"), (err,browser,status) ->
      browser.fill("email", "#{user.email}")
             .fill("password", "#{user.password}")
             .pressButton "Login", cb
    return
  return [label,fixture]

Note that the function returns an array of arguments to be supplied to the vows-bdd method. Also note that the fixture method is using this — which will point to the vows context when the test is evaluated — and that the fixture returns undefined to indicate to vows that the test should be performed asynchronously.

I think this new syntax works really perfectly for integration tests; it goes a long way to supporting declarative testing style.

As always, please let me know if you run into any problems with the library or have any suggestions!

Thanksgiving Week Links

| Comments

I’ve never been a fan of links posts – they always feel like “clips episodes” from sitcoms to me – but I’ve realized that they can be pretty helpful, if they’re well curated. I’m going to be experimenting with the “well curated” sort of links posts. Please feel free to yell at me on twitter if these get boring.

  • A scaffold for your node – scaffoldit is a customizable scaffold generator for your nodejs projects. I don’t think that there’s that much boilerplate for express based apps, but this library is still pretty helpful for getting my tests and basic app configured quickly.

  • Basic metaprogramming in Ruby – If you’re new to Ruby and are confused by some of the metaprogramming enabled by methods like repond_to? and method_missing, check out this helpful post from the Intridea blog.

  • Build first, talk later – Spencer Fry, founder of Carbonmade, offers some fine advice to show don’t tell – a prototype is worth ten thousand words. I particularly like his observation that “The best thinking about your product will come from actually building it.”

  • Productivity geekery – Brett Terpstra reviews the mother-of-all-menubar-apps, Dropzone. I haven’t bought it yet myself, but I’m pretty close to pulling the trigger.

  • Writing your readme – Awhile back, nodejitsu offered some solid advice on setting up your node project’s package.json file. Now they’re back with some more great advice, but this time it’s more universal: how to write a helpful readme for your next open source project.

  • After reading Umair Haque’s excellent New Capitalist Manifesto, I’ve been thinking a great deal about the values of sustainability in business and how value cycles drastically improve upon value chains. I was excited to see Fred Wilson explore the same issues on his blog:

sustainability is all about figuring out how to be in business forever. It is about business models that are win/win and lead to happy long term customer and supplier relationships. It is about avoiding the temptation to overeach. It is about avoiding the temptation to mazimize near term profits at the expense of long term health. It is about adapting the business to changing market dynamics. It is about building a team and a culture that can survive the loss of the leader and keep going. And it is about many more things like this.

Fix That Commit!

| Comments

While it sometimes seems as if everyone has already switched to git (or a similar distributed version control system), I still meet people who are only leaving subversion behind now. A lot of git’s idioms are impenetrable to those who are new to it, but the presence of free resources like Pro Git and git ready make the adjustment much easier.

Even though I’ve used git for awhile, I still need to look up the best way of performing a task every now and then. One trick that comes in handy is editing existing commits. git --amend allows for adding new files or changes to a previous commit, but you can have even more control than that — changing any pre-pushed commit in your history.

Just get the hash of the commit you want to change. With a simple git rebase <commit>^ --interactive, you can then make any changes you want. For each file, just type git add <file>. When you’re done, git commit --amend and git rebase --continue will finish up your editing.

It’s always useful to review and cleanup your commit history before pushing your changes upstream or issuing a pull request. With the ability to revisit any previous commit, you can be more comfortable in a ‘commit-all-the-time’ workflow.

Cleaning Up Yours Vows

| Comments

Learning a framework as you’re TDD-ing a project can be dangerous. But even if you know what you’re doing, some of the conveniences of node.js can make you a bit sloppy with your code. Namely, the ability to pull functions from files as you need them and pass them around makes for some interesting problems.

foo.js
1
2
3
4
5
6
exports.add = function(a,b) {
  return a+b;
}
exports.subtract = function(a,b) {
  return a-b;
}
bar.js
1
2
var add = require('foo').add;
console.log(add(1,2)); // 3

If your functions are free of side effects, you’re not exactly committing a serious coding sin. But go beyond the simple example above — starting to pass around whole objects, or breaking the law of demeter — and soon your code doesn’t feel right.

I quickly ran into this problem with my vows tests. As I was about to merge a feature branch to master, I reviewed my code and was a bit horrified at what I saw in my tests:

user_spec.coffee
1
2
3
4
5
6
7
{cleanupDB} = require "../helpers"
{vows,server} = require "vows"
mongoose = require "mongoose"
User = mongoose.model "User"
assert = require "assert"
Sinon = require "sinon"
{Factory} = require "../helpers"

And this was just one of my tests. Yikes. Lots of bad things going on here:

  • My test has a dependency on my model implementation, and not just the model itself; if I switch the model off mongoose in the future, my test itself will need to change.
  • My test has a dependency on a particulra spying/mocking framework (Sinon)
  • There’s a lot of confusing imports; why is server required off of vows?
  • Repeating requires – one for cleanupDB and one for Factory.

Bad bad bad.

My tests needed to be refactored to deal with this madness. I realized that there was repeated code throughout my vows tests; not only could I clean things up with some proper encapsulation, I could DRY my vows as well.

One cool feature of node is that if you include an index file in a directory, that file is loaded when you require the directory. So I created a new spec/helpers directory, and placed an index file inside.

spec/helpers/index.coffee
1
2
3
4
5
6
process.env.NODE_ENV = 'test'

module.exports =
  Server:  require "#{__dirname}/server_helpers"
  Test:  require "#{__dirname}/test_helpers"
  Model:  require "#{__dirname}/model_helpers"

And each of these helper files now encapsulates logic and functionality that I use across my tests:

server_helpers
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
http = require "http"

exports.port = port = 3003
server = (require "#{__dirname}/../../app")
server.ready = (callback) ->
  if @active
    process.nextTick callback
  else
    @active = true
    server.listen port, (err,result) ->
      process.nextTick callback
  return

process.on "exit", ->
  if @active then server.close()

wait = ->
  if !@active
    process.nextTick wait
  else
    return

server.ready wait

makeRequest = (url,params,method,callback) ->
  params ||= ""
  encoding = 'utf-8'
  server.ready ->
    request = http.request
      host: "127.0.0.1"
      port: "#{port}"
      path: url
      method: "#{method}"
      headers:
        'content-type': "application/x-www-form-urlencoded"
        'content-length': params.length

    request.on 'response', (response) ->
      response.body = ''
      response.setEncoding encoding
      response.on 'data', (chunk) ->
        response.body += chunk
      response.on 'end', ->
        callback null, response
    if params
      request.write params
    request.end()


exports.server = server

exports.get = (url,params,callback) ->
  if arguments.length == 2
    callback = arguments[1]
    params = null
  makeRequest url,params,"GET",callback

exports.post = (url,params,callback) ->
  makeRequest url,params,"POST",callback
test_helpers.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Sinon = require "sinon"
assert = require "assert"
http = require "http"
Model = require "./model_helpers"

exports.spy = (object,method) ->
  Sinon.spy object, method

exports.stub = (object, method, fn) ->
  Sinon.stub object, method, fn

exports.spyRender = ->
  @response = http.ServerResponse.prototype
  Sinon.spy @response, "render"

exports.spyModel = (klass,method) ->
  Sinon.spy (Model.getType klass), method

exports.assert = assert
model_helpers.coffee
1
2
3
4
5
6
7
8
9
10
11
mongoose = require "mongoose"
cleaner = new (require "database-cleaner")("mongodb")

exports.cleanupDB = ->
  mongo = mongoose.connection.db
  cleaner.clean mongo

exports.Factory = (require "#{__dirname}/factories").Factory

exports.getType = (Klass) ->
  mongoose.model Klass

My test logic dependencies are clean and encapsulated, making for both clearer requires blocks and clearer tests themselves.

user_spec.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{Model,Test,Server} = require "../helpers"
vows = require 'vows'
User = Model.getType "User"

#code removed for brevity

  .addBatch
    "Hashes password:":
      "when a new user is created":
        topic: ->
          @user = Model.Factory.build "User"
          Test.spy User, "makeSalt"
          Test.spy User, "hashPassword"
          @user.save @callback
          return

        "it creates a salt and stores it": (err,user) ->
          Test.assert.ok User.makeSalt.calledOnce
          Test.assert.ok user.salt == User.makeSalt.returnValues[0]

        "it encrpyts the password": (err,user) ->
          Test.assert.ok User.hashPassword.calledOnce
          Test.assert.ok User.hashPassword.calledWith @user.password

      teardown: ->
        User.hashPassword.restore()
        User.makeSalt.restore()
        Model.cleanupDB()

Indie Productivity

| Comments

Being a contract web developer means working in a large number of enterprise environments. While clients and projects vary dramatically, enterprise environments almost always share certain characteristics in common: locked down networks, limited use of open source libraries (and certainly no contribution!), extreme caution regarding new technologies, and reliance on libraries and tools which some might consider… deprecated. Most of these characteristics are perfectly logical, given the complexity of enterprise projects and the security required by legal considerations. Enterprise software is frequently disregarded as sloppy, boring, uncreative, and poor — and I’ve certainly worked on these kinds of projects, and dealt with some frustrating situations — but classifying all software in this way is unfair. That said, even the best of enterprise projects feel constraining compared to independent work.

Recent developments have certainly improvemed the enterprise work environment. The proliferation of iOS devices has not only brought Macs into the traditionally Windows-only world of the enterprise; it’s brought a new focus on standards-based webapps, which has forced a reconsideration of existing technology stacks. As enterprises have adopted dynamic languages and agile approaches — albeit slowly — they’ve begun upgrading their toolsets, as well. Github’s announcement of an enterprise plan demonstrates that it’s starting to feel a little bit more human within the confines of corporate intranets.

But even as the enterprise has evolved, the improvements made for individual developer productivity have exploded. The ease with which a single developer can build and deploy a scalable, cross-device, and revenue generating app is beyond remarkable. The maturing of tools, languages, development environments, and deployment strategies has created a fantastically productive environment. To name a few favorites:

  • Macbooks – The new Macbook Airs, when fully tricked out, offer incredibly powerful development workhorses weighing less than 3 pounds and costing less than $2k

  • Homebrew – A package manager for Mac OS, making that Macbook purchase perfect

  • Heroku – Have an idea for a new project? Deploy it for free. Want to scale it? Flip a switch

  • Chef and Puppet – Want more control than Heroku offers? Fine, manage your own boxes with a sane devops solution that you can take with you.

  • Git and Github – Who could have ever imagined that managing code could be so enjoyable?

  • zsh and oh-my-zsh – Tab completion, customizable plugins, persistent Git HUD

  • The incredible profusion of programming languages, libraries, and frameworks – Scala, Clojure, node.js, the Play framework, NoSql solutions, nginx, to say nothing of the maturing of Ruby (especially Rails) and Python – all of these technologies make it easier than ever to work in one’s preferred style without sacrificing power or performance. The communities around each of these technologies, empowered by twitter, StackExchange, and Github, ease learning curves and offer helpful answers to any questions.

  • The Apple App store, Square, Stripe, Recurly, and Samurai enable developers to make money on their ideas and apps with far less effort than in the past.

Is there any other industry in which an individual has such a dramatic advantage in tools, cost, and agility over large organizations?

It’s an exciting time for indie developers. And the future keeps looking better.

Back From Vacation

| Comments

I just returned from a fantastic vacation to London and Copenhagen. I’d visited London, before but had never been to Copenhagen, or any Scandinavian country. As an engineer, I could barely wrap my mind around the brilliant efficiencies of the city. The train system is a wonder – incredibly efficient, clean,and comprehensive, with the ability to get anywhere easily, and even allowing sales of travel tickets via text message. My heart warmed at the first site of a flotilla of bike-commuters sailing by on our walk to our hotel. The Danes themselves consistently impressed us with their warmth and hospitality. I look forward to returning soon.

My brain is struggling to return to coding productivity after its extended vacation, so I’ve mostly been reviewing my RSS reader to aid in the transition. Assaf Arkin, to whom I owe a massive debt for his creation of Node testingtool Zombie.js, wrote a great article on Self that deserves mentioning. Self, as most JS developers know, played an important role in inspiring Brendan Eich’s creation of Javascript, but I was unaware of the details of the language.

Assaf’s whole article is worth reading, but one particular quote stood out:

language and environment come together to achieve a common goal: to create an environment that is malleable, that allows learning through sharing and exploration, that uses minimalism and consistency to foster reuse.

Minimalism, consistency, malleability.

These words work not just as signposts of good language design, but of everything from API construction to individual units of code. I’m certainly planning on using them as my mantra as I slowly get back up to speed with work.