You’re reading Signal v. Noise, a publication about the web by Basecamp since 1999. Happy !

Signal v. Noise: Programming

Our Most Recent Posts on Programming

Learning Rails at The Starter League

Jason Fried
Jason Fried wrote this on 10 comments

This fall I’ve been taking the Rails for Designers class at The Starter League here in Chicago.

My classmates come from as far as South America and as close as a few desks down (fellow 37signals designers Jamie, Mig, Jonas, John, and Shaun are also taking the class). One student, not in our class, came over from Hong Kong.

My classmates also come from a variety of backgrounds. Some are designers with no programming experience. Others are programmers who work in languages other than Ruby. There’s also a lawyer and a couple Chicago Public School teachers, too. There’s a good 30 year age range spread as well. It’s a diverse and dedicated group. They’re inspiring people.

Class ends in a few weeks, and applications for the next quarter close in a few days, so I thought it would be a good time to reflect on the experience.

Was it worth it? Absolutely. Would I do it again? Absolutely. Would I recommend it to someone else? Absolutely.

I’ve been around Rails since the beginning. At 37signals, designers and programmers work together on the same codebase, so every 37signals designer has seen plenty of Rails in their time. And I’ve tried to pick it up on my own over the years by reading books or getting a few crash courses from co-workers. But it never clicked like it does now after taking this Starter League class.

I think the magic is in how Jeff and Raghu, the two teachers, understand how to teach absolute beginners. Teaching beginners is a unique skill. It requires a ton of patience and a truckload of empathy. You really have to start right at the beginning and assume nothing about what people may or may not know. You have to think like a beginner again. That’s really hard.

Am I a fantastic programmer now? No way. Would I hire myself as a programmer at 37signals? No, I wouldn’t. But that wasn’t my personal goal.

However, after just a few months I have a solid basic understanding of Ruby, Rails, and what programming is all about. I can build a database-backed web app on my own. I can pull in data from external APIs, manipulate it, and return it formatted the way I want. I can read and understand a bunch of code in the Basecamp code base that was complete greek to me before. I know what this code does, why it is where it is, how to manipulate it enough not to break the basics, and how to make changes without having to ask for help. That’s a huge leap forward for me, and it means fewer “hey, can you do this for me?” questions for my co-workers.

I can’t tell you how liberating it is to be able to find my way around our codebase now. It makes me a better designer, too. I can quickly prototype new ideas without having to get someone else involved. Big win. Further, I know where to go from here if I want to dedicate myself to getting better.

And on top of all of this, I feel like I’ve gained an invaluable skill: The ability to see problems from a new angle. Learning how to program has introduced me to a new perspective on problem solving, a new way of thinking. That doesn’t come around often and I’m thrilled to have found it at The Starter League.

If you’re interested in learning Rails – even if you don’t have a single bit of experience – check out The Starter League’s Web Development Class. Just want to learn HTML/CSS? Check out the HTML/CSS class (and there’s an advanced HTML/CSS class, too). There’s even a User Experience Design class. Want to learn visual design or how to improve your current design skills? Our very own Mig Reyes is teaching the Visual Design class.

Applications for The Starter League Winter session are due by Sunday. If you’re on the fence, hop off and apply. You will not regret it.

(Disclosure: 37signals is a minority investor in The Starter League)

Pattern vision

David
David wrote this on 16 comments

Design and programming patterns are wonderful ways of disseminating knowledge. It’s immensely satisfying to bring solution to a tough problem by applying a perfect-fit pattern.

But success with pattern applications is like taking that first innocent bump. You quickly want more of what made you feel this good. And buoyed by the high of a perfect fit, it’s easy to develop pattern vision where code, like Tetris shapes, become mere blocks for fitting into the pattern holes.

With this infliction, you will invariably drift away from the original intent of making specific and immediate pain go away. Where the perfect and legitimate fit will remove a thorn that’s obviously hurting the code right now, the speculative fit pretends to do the same for future hurts.

Now that’s an honorable intention. A pinch of prevention over a pound of cure, right? Only, it rarely works out like that. Speculative pattern applications to avoid future, possible ails is a form of fortune telling. It’s the reason YAGNI was coined.

The further down this rabbit hole you go, the farther away from practical improvement you’ll end up. Go deep enough and the pattern vision turns into articles of faith. Inheritance is always bad, only composition can be our true savior! Only standalone command objects can give us the reusability this application needs!

Turning patterns into articles of faith takes them out of the realm of rational discussion. Code either adheres to the holy patterns or it doesn’t. If it does not, the programmer must first repent, say his 25 rose-delegations, and then swear never to let an opportunity for a policy object extraction pass by him again!

The naming of many design principles supports this theological world view that patterns also at times inhibit. It’s obvious that you’re a sinner if you break The Law of Demeter and of weak will if you forgo the Single Responsibility Principle.

Patterns are best thought of like helpful guidelines and suggestions, not laws, not imperatives. It’s a written account of “hey, if you have this problem, you can try this thing to make it better”. Their core value is transforming some code to better code in a way that’s immediately obvious to the writer.

Evaluating such improvement is easy. You look at the code you had before applying the pattern and after it. Did it make the code simpler to understand? Clearer? Prettier? If you can’t easily see whether that’s so, you’ve been sold.

Automating with convention: Introducing sub

Nick
Nick wrote this on 21 comments

When I started my on-call shifts, we had pretty little in the way of automation for day-to-day issues. Tasks like SSH’ing into our cluster, starting a Rails console, or doing a deep search through our gigantic mail directories, were either shelved away in someone’s bashrc, history log, or just ingrained into someone’s memory. This pain was also felt by a few other of my fellow programmers, and we started cobbling together a Git repo simply named “37s shell scripts”.

This repo started very innocently: a little Ruby script named console that mapped a product name (basecamp) to a server name inside of our cluster (jobs-03), SSH’d in, and then ran a production Rails console. Several more bash and Ruby scripts started to trickle in as we started to share more of our personal code that we used when on-call. Eventually Sam laid down a foundation of bash scripts and directories borrowed from rbenv, and dubbed it “37”.

Continued…

Running beta in production

David
David wrote this on 22 comments

We’re constantly working on new features, improvements, and technical upgrades for Basecamp. Many of these changes need to be experienced in the wild to guide their evolution. We need to live with them in our daily use of Basecamp to see whether what seemed like a good idea is actually a good idea.

To this end, we run six different beta servers that all point to the same production database. We’ve found it impossible to accurately evaluate a feature unless it’s being used in anger with real data that actually matters. Evaluating changes against a staging server that’s running an old copy of the database just doesn’t cut it.

The way we book a beta server for use with a certain branch is simple: It’s just in the title of the BCX Campfire room.

When you’re done with a beta server, you change the title to “available”. When you need a beta server, you change it to the name of the running branch.

To select a given beta server, we’ve added a drop-down to all 37signals’ staff accounts within Basecamp itself.

You just pick the server you want to run on and it’ll route you to the beta environment running the branch you’re looking to try out.

Long-term exposure to upcoming features is a great way to get them just right. But it’s also a great way to realize that what you thought was a great idea just wasn’t good enough to ship. We’ve killed many features and changes to Basecamp after living with them for a few weeks. Often times, the most important features are the ones you don’t ship.

Clarity over brevity in variable and method names

David
David wrote this on 66 comments

Many programmers have a natural preference for short variable and method names. I doubt many would recognize this preference as a trade of brevity for clarity, but that’s often exactly the result. This is especially true if you subscribe to the ridiculous Church of 80-character Lines.

It need not be that way. Writing terse code can be a joy even if you spell things out in abundant detail. Modern programming languages are expressive enough that what you save in laborious boilerplate can be spent on clarity — and you’ll still have plenty of lines left over for a dance.

And most certainly, you’ll hardly ever need to abbreviate anything. I cringe when I see ext for extension, cp for copy, or worse, application-specific abbreviations sure to be forgotten two months after you left the project.

At times being exceedingly clear will seem almost silly at first glance. The name of the method or variable can be longer than the operation being performed! But the silliness quickly dissipates the first time you return to a piece of code and know exactly what it does.

Here are a few examples of long method names from the new Basecamp code base:

def make_person_an_outside_subscriber_if_all_accesses_revoked
  person.update_attribute(:outside_subscriber, true) if person.reload.accesses.blank?
end

def shift_records_upward_starting_at(position)
  positioned_records.update_all "position = position - 1",
    ["position >= ?", position]
end

def someone_else_just_finished_writing?(document)
  if event = document.current_version_event
    !event.by_current_creator? and event.updated_at > 1.minute.ago
  end
end

If you work hard at being clear in your naming, you’ll also rarely need to write comments for the code. Comments are generally only needed when you failed to be clear enough in naming. Treat them as a code smell.

“The UNIX System: Making Computers More Productive”, from 1982. Brian Kernighan, Dennis Ritchie, and Ken Thompson talk about what UNIX is, how to use it, and show off some live coding too. Thanks to Tony Arcieri for sharing this!

Go code spelunking with me in the all new Basecamp! You’ll see how we build Rails apps at 37signals and learn several exciting Ruby and JavaScript patterns that you can use. There’s also a writeup of some of the best chunks from the talk to check out.

Levels of aspiration

David
David wrote this on 31 comments

Debates over technology, technique, and process often go nowhere because the participants are arguing from different levels of aspiration.

You’re unlikely to convince someone they should switch to programming Ruby for its beauty, if they’re merely looking to make a living as a single consultant serving local businesses in Schaumburg, Illinois.

Questions such as “does this run on my existing web host?” or “will my clients want something their nephew web designer hasn’t even heard of?” matter far more. Their aspirations are local, finding something that (sorta) works, and getting paid.

It’s easy to snub your nose at that if you have grander aspirations, but there’s a lot of software to be written in this world, and we need all sizes and shapes to get it done.

The third largest landscaper in Schaumburg is probably operating from the same level of aspiration as our single consultant, so there’s a great fit.

You can think of these levels of aspiration in terms of both geographical and technical hierarchies. Here’s a take on what a hierarchy of technical aspirations could look like for programming:

You can imagine a similar hierarchy for the geographical angle with the levels being Local, City, Regional, National, Global.

The key to a fruitful debate is to first establish at what level the person you’re talking to resides, and then use arguments from the next level up. But if they’re entirely content with where they are, then it’s probably better to live and let live.

To help someone move up the hierarchies, they have to have an intrinsic desire to do so. Arguments like “but it works” or “it gets the job done” are tell-tale signs of someone happy at the lowest level of the technical hierarchy and your cue to just quietly back out of the debate.

Announcing Pow 0.4.0 with xip.io support

Sam Stephenson
Sam Stephenson wrote this on 34 comments

We’ve just released version 0.4.0 of Pow, our zero-configuration web server for Rails development on OS X.

There are several new features in this release, including port proxying and better support for zsh users, but my favorite is a tiny addition that makes a huge difference when testing your apps on mobile devices.

Pow has always made it easy to access Rails apps on your computer with its built-in .dev domain. Just symlink your app into the ~/.pow directory and visit http://myapp.dev/ in your browser.

But what about testing your apps on mobile devices, or in IE? Pow’s .dev domain only works on your local machine.

Until now, testing on other computers required modifying /etc/hosts or setting up a custom DNS server on your router. Now we’ve fixed that, too.

Introducing xip.io, the magic domain name

Pow 0.4.0 has built-in support for xip.io, a free service from 37signals that provides wildcard DNS for any IP address.

With xip.io you can access your Rails apps from devices on your local network, like iPads, iPhones, Windows VMs, and other computers. No configuration required.

Say your development computer’s LAN IP address is 10.0.0.1. With the new version of Pow, you can now access your app at http://myapp.10.0.0.1.xip.io/. And xip.io supports wildcard DNS, so any and all subdomains of 10.0.0.1.xip.io resolve too.

Read more about xip.io at http://xip.io/ or check out the full source code on GitHub.

Installing and upgrading

See the full 0.4.0 release notes and install or upgrade with one simple command from your terminal:

curl get.pow.cx | sh

As always, the user’s manual and annotated source code are available for your perusal.

Keynote by David from RailsConf 2012 on progress, curiosity, fear, and the danger of easy-bake ovens.