Destroyed 0003

I’m blogging my way through Gary Bernhardt’s excellent Destroy All Software series of screencasts. If you write software, you should probably go buy it today.

In Episode 3, Gary builds a simple version of RSpec, using TDD. I’d seen him do something similar at the Testing in Python BOF at PyCon this year, when he trolled the audience with Ruby, challenging the assertion that “RSpec is hard!” with derision and flair.

The interesting part about the screencast, then, was watching him drive his coding with tests. I’d describe myself as a “testing believer”, but I think I get tripped up at the same place a lot of people do: where do you begin? How do you know what test to write first, when you don’t even know what the call interface is going to look like?

So I found myself exclaiming as he began: “that test doesn’t do shit!” Indeed, the first test doesn’t do anything other that test that there’s this describe thing, that happens to take an argument. So the primary lesson I took away from Episode 3 was that when it comes to TDD, you’d don’t have to know where you’d end up. You just need to start.

The other lesson was that the cycle isn’t “write tests, write code, fix code until tests pass.” It’s more like “write a test, write a little code, repeat”. And there’s an additional step that I don’t always remember: re-read your previous tests, and refactor as needed.

It’s interesting watching these screencasts, and feeling like I’m learning, even though I don’t really know the language (Ruby). In this episode I learned a little more about Ruby’s blocks: the interpreter silently ignores a block passed to a function that doesn’t expect it. I wonder why that is?

I also learned that instance_eval is the core of a lot of Ruby DSLs, and runs a block as if it were applied to an instance (I think I have that right). I think the Python equivalent would be to eval some code with an instance’s dict as the local context.

author:Nathan Yergler
category:destroyed
tags:til
comments:

Destroyed 0002

I’m blogging my way through Gary Bernhardt’s excellent Destroy All Software series of screencasts. If you write software, you should probably go buy it today.

Episode 0002 of Destroy All Software talks about nil in Ruby. I’m not a Rubyist. I may be someday, but I’m not today, so I just imagined he was talking about None in Python with weird syntax. This episode is really how returning a nil value can lead to exceptions that are miles away from where they actually originated. Gary demonstrates this with a little Rails app, and I found myself nodding along: I see this with some frequency in the Eventbrite codebase, where a domain model’s property is set to None, and at a later point other code tries to call a method on that value.

You can, of course, write your own property descriptor (in Python) that checks for None and raises an exception when that value is set. At least then the error is localized to when it’s really being set to (or returning) None. But what you really want is to avoid the error altogether. Gary shows a couple ways to potentially do that, including inverting the relationship between domain models, and introducing a new model instead of just setting a property on an existing one.

author:Nathan Yergler
category:destroyed
tags:til
comments:

Destroyed 0001

Some people blog their way through Knuth or SICP. My attention span is somewhat shorter lately. I’ve recently begun watching Gary Bernhardt’s excellent Destroy All Software screencasts, and I thought it’d be fun to blog my way through it with a series of short posts on what I learned from each episode. I’ve watched a few as I start this, and I think that if you write software and care about writing good software, you should probably go buy DAS now.

I watched Episode 1 on my way to OSCON about a week ago. In it Gary works through building a small bash script to calculate some statistics on a git repository (for example, how many lines of code there were at given points in time). The git plumbing bits were pretty interesting, but it was the actual process that was really educational.

One of the first things he also does is map a key to save and then run his script. I almost found myself coveting Vim for a moment, because it seems obvious now that having an immediate feedback loop is actually superior to switching between Emacs and a terminal.

As Gary builds out the script, he points out a few things, like using set -e, and “always quote your arguments”. (It makes a missing argument fallback to an empty string, which programs like grep are perfectly happy with.) That sort of casual, fingertip knowledge is a joy to watch. I guess I haven’t written enough in bash to know better than to check my exit codes manually for things. set -e is obviously better. Way better.

And have you ever considered that bash control structures like while and for have a stdin and stdout? They do. It seemed obvious once I saw him do it, and when I think about the way bash works, it makes sense in a consistency sort of way. But until now I’d never considered piping the output of, say, grep to a control structure.

Watching DAS S1E1 I learned a few things about shell scripting that seem really fundamental, which I wish I’d have known about for, well, years. I also realized that I have this weird mix of git knowledge: I understand that it’s a directed acyclic graph and a bunch of the underlying structures. I also am proficient at using magit to manipulate a repository within Emacs. The git porcelain? Not so much.

Finally, I thought it was interesting to see and listen to Gary refactoring a bash script using some of the same principles that I use when looking at Python code. Specifically, wanting to make code easy to read, not just execute.

author:Nathan Yergler
category:destroyed
tags:til
comments: