About

James Golick

James Golick is an engineer, entrepreneur, speaker, and above all else, a grinder.

As CTO (or something?) of BitLove, he scaled FetLife.com's traffic by more than an order of magnitude (and counting).

James spends most of his time writing ruby and scala, building infrastructure, and extinguishing fires.

He speaks regularly at conferences and blogs periodically, but James values shipping code over just about anything else.

Latest Tweets

follow me on Twitter

James on the Web

Look out Ryan Bates - There's a New Screencast in Town

Jan 27 2008

So, I'm sitting there on Friday evening working on a screencast introduction to attribute_fu, when Fabio Akita sends me an email to tell me he just created one for resource_controller! It was like he'd read my mind.

Fabio was nice enough to agree to let me put some title screens on his r_c screencast, but I couldn't seem to get it to export while still looking decent. So, here's the first episode of GiraffeCasts (for those of you who don't know, my company is called GiraffeSoft), and Fabio's awesome resource_controller introduction.

Episode 1: attribute_fu

Episode one is a quick walk through the basics of attribute_fu. Get it here.

As promised, here is the code from the screencast:

## _task.html.erb
<p class="task">
  <b>Title:</b><br/>
  <%= f.text_field :title %>
  <%= f.remove_link('Remove') %>
</p>
## _form.html.erb
<div id="tasks">
  <%= f.render_associated_form(@project.tasks, :new => 3) %>
</div>
<%= f.add_associated_link('Add Task', @project.tasks.build) %>
class Project < ActiveRecord::Base
  has_many :tasks, :attributes => true
  
  private
    before_save :remove_blank_tasks
    def remove_blank_tasks
      tasks.delete tasks.select { |task| task.title.blank? }
    end
end

To get attribute_fu:

$ piston import http://svn.jamesgolick.com/attribute_fu/tags/stable vendor/plugins/attribute_fu

Fabio's resource_controller Screencast

Fabio Akita gives an excellent tour of resource_controller, in screencast form. Get it here.

See Ya Next Time

That's all for today. Check back for more GiraffeCasts!


Ruby Reddit

Jan 25 2008

When reddit announced that they were going to be offering users the ability to create their own reddits, I sent them an email asking for a beta account. Guess what? They gave me one!

So, rubyists everywhere, here it is: our very own ruby reddit!


Why Distributed Version Control Matters to You, Today

Jan 20 2008

If Linus's talk about git made you feel like a moron, rest assured you're not alone. Distributed version control is one of the most poorly explained topics in software, today. There are plenty of people saying that you should use it, but nobody has done a great job of explaining why. Here's my take.

WTF is Linus talking about?

First, let's talk about exactly what distributed version control is. The most common approach to describing a decentralized system is to present the reader with an image like this one, taken from the mercurial page called UnderstandingMercurial:

If that image makes any sense to you (and you're new to distributed version control), congratulations. The rest of us need a clearer description.

The best place to start is with the differences between centralized, and decentralized version control. With a centralized system like Subversion or CVS, there is a single copy of the repository; it typically resides on a server somewhere. When a developer works with the code, they receive something called a "working copy" from the central repository. The working copy contains enough information to interact with the central server, but does not contain the revision history for the project, nor the branches or tags (though, the branches and tags can often be explicitly requested).

With a decentralized system, the opposite is true. Instead of checking out a working copy, the developer works with the entire repository, including the entire revision history of the project and all the branches and tags. The copy that the developer receives is identical to the repository they fetched it from. Commits, branches, and tags occur locally, on the copy of the repository that the developer made. Changes can then be pushed and pulled to or from a public repository somewhere, another developer's repository, or anywhere else that a repository exists.

So?

Usually, when you want to get a build or source distribution of open source code, you head the project's main website. The project's repository is closely guarded, with commit rights only awarded to a select few. Anybody wishing to make changes to the source must first check out a working copy from version control, submit a patch, and hope that it is accepted.

When every developer has a full copy of the repository on their machine, the hierarchy of open source projects is all but eliminated. Any developer who wishes to work on the source code can clone the repository, commit as much code as they want to it, receive the changes from any other developer's cloned repository, and publish their work for other developers to use, or pull back into their own repositories. In a decentralized system, it doesn't matter who has the "...keys to the source repository..." (it actually says that on the rails core team page — take a look for yourself). If the original author continues to maintain the best version of the code, great; if not, users of that code can begin to pull from whoever does have the best version.

Really!

Entirely theoretical software articles are lousy — so, I always try to provide examples out of real software; this article is no exception.

Many (maybe most) rails plugins are inactive. They were created to scratch an itch, published, kept up to date for a few months, and then left with no maintainer. Since rails plugins largely reside in subversion repositories, nobody can continue development without losing the entire revision history of the project, and going to the trouble of setting up a public svn server.

Markaby is no exception to that rule. When I tried to use it in a recent project, I found that it was incompatible with rails 2.0.2. According to markaby's subversion logs, the last change was November 24th, 2007, a few weeks before that version of rails was released. Luckily, I was able to find a ticket in rails trac with instructions on how to hack a fix in to the plugin — a solution that worked great for me, but wouldn't work for a user who didn't know their way around plugins. Without commit access, normally I wouldn't be able to offer my fix publicly.

Not so with a distributed system! I was able to use git-svn to pull Markaby into a git repository. I've published my changes, and now anybody can grab a working version of Markaby by typing the following in to a command prompt:

  $ git clone git@github.com:giraffesoft/markaby.git

Even cooler than that, somebody with commit access can grab the changes, and push them back into subversion, including commit messages, and everything! Anybody who clones the git repository can still pull changes from _why's subversion repository if it ever becomes active again. If not, development can continue anywhere, and be done by anybody. That's the beauty of decentralization.


Taking Style Tips from Natural Language

Jan 13 2008

When one speaks of the readability of a computer program, they refer to the ease with which the source code is read by a human. More recently, with languages like Ruby and Python, one often hears praise for sections of code that seem to read like natural language. That sort of code is easier read, but seems to be more challenging to write. If english-like is what we're after, perhaps style manuals can teach us something about writing code.

Having always been interested in writing English, I've read several books on style. The text that I continue to return to is Strunk & White's The Elements of Style. It has served me well as a reference for writing English; let's see how it does for Ruby.

Lesson One: Put statements in positive form.

The rule from Strunk & White:

Make definite assertions. Avoid tame, colorless, hesitating, noncommittal language. Use the word not as a means of denial or in antithesis, never as a means of evasion.

Elements of Style provides a short explanation of each rule, followed by several illustrative examples. Each example contains a violating passage, and a correction. Here's an example from this rule...

The violating example:

He was not very often on time.

...is corrected by:

He usually came late.

Yes, Strunk and White provide refactorings; I'll do the same.

if !@post.save
  render :action => 'create'
else
  redirect_to post_url(@post)
end

That example is rather simple. It says: If the post doesn't save, render the create action, otherwise, redirect to the post's url. I think we can agree that in most cases, it would be better to express that as follows:

if @post.save
  redirect_to post_url(@post)
else
  render :action => 'create'
end

By putting our statements in positive form, we have refactored that code to read: If the post saves, redirect to its url, otherwise render the create action. Because we have eliminated the negation, the code reads more smoothly and easily. While that is an obvious example, it shows that there is something to this. Let's look at another rule.

Lesson Two: Use the active voice.

The rule from Strunk & White:

The active voice is usually more direct and vigorous than the passive.

The violating example:

It was not very long before she was very sorry that she had said what she had.

The correction:

She soon repented her words.

This rule doesn't apply as directly, but I have always loved it as a style guideline for code. Take this rather common example:

[1, 2, 3].each do |number|
  if number.even?
    # do something with an even number
  end
end

That example says: With each element in this array, if that element is even, do something with the even element. Collecting the desired elements that way reads passively. Making use of some more of our tools from ruby's Enumerable module, we can refactor it to use the active voice.

[1, 2, 3].select(&:even?).each do |number|
  # do something with an even number
end

The refactoring says: With all of the even numbers in this array, do something. It reads shorter, and expresses the intent of the coder more directly.

From the Real World

The next example we're going to look at comes from ActionController::Base (a central class in rails). I have selected a few illustrative branches from a conditional that spans some sixty lines, in a method that spans nearly one hundred. It is the rendering logic:

if file = options[:file]
  render_for_file(file, options[:status], options[:use_full_path], options[:locals] || {})

elsif template = options[:template]
  render_for_file(template, options[:status], true)

elsif inline = options[:inline]
  add_variables_to_assigns
  render_for_text(@template.render_template(options[:type], inline, nil, options[:locals] || {}), options[:status])

elsif action_name = options[:action]
  template = default_template_name(action_name.to_s)
  if options[:layout] && !template_exempt_from_layout?(template)
    render_with_a_layout(:file => template, :status => options[:status], :use_full_path => true, :layout => true)              
  else
    render_with_no_layout(:file => template, :status => options[:status], :use_full_path => true)
  end
end

It says (bear with me): If the file option is present, render the file, or if the template option is present, render the template, or if the inline options is present, pass the instance variables to the template, and render some inline text from the controller, or if the action option is present, render that action. Note: that transliteration has been shortened somewhat.

The passiveness of a multi-branch conditional damages clarity; it creates a meandering experience for the reader. The problem is that separate concerns are being forced together. In the case of the render method, the conditional determines which type of rendering to perform, and contains the actual code to perform that type of rendering.

Long conditionals also seem to resemble run-on sentences. Since one must remember all of the context as they read through the branches of this sort of structure, it quickly becomes difficult to follow. It would be better to separate the decision from the specific rendering logic; that will make it easier to be more direct.

def render
  render_types   = [:file, :template, :inline, :action]
  type_to_render = render_types.detect { |render_type| options[render_type] }
  send(:"render_#{type_to_render}")
end

def render_action
  template = default_template_name(action_name.to_s)
  if options[:layout] && !template_exempt_from_layout?(template)
    render_with_a_layout(:file => template, :status => options[:status], :use_full_path => true, :layout => true)              
  else
    render_with_no_layout(:file => template, :status => options[:status], :use_full_path => true)
  end
end

def render_inline
  add_variables_to_assigns
  render_for_text(@template.render_template(options[:type], inline, nil, options[:locals] || {}), options[:status])
end

def render_template
  render_for_file(template, options[:status], true)
end

def render_file
  render_for_file(file, options[:status], options[:use_full_path], options[:locals] || {})
end

Now, it reads: The render types are file, template, inline, or action. The type to render is the one that is present in the options hash. Call the method named: render underscore the type to render. Refactored, each of the ways of rendering gets its own method, and those methods have a name. That way, it is clear what each of those blocks of code does, and what we're doing when we call it; we needn't decipher a conditional to find our way to the pertinent logic. Separating code in to small chunks housed by well named methods allows us to express our intentions directly.

As an aside, writing methods this way is far more testable. In its original form, the render method does many different things, depending on the parameters it receives. Testing it would be an exercise in managing side effects. You'd also be testing two different things at once: does it reach the correct branch of the conditional, and does it execute the rendering properly. With the simple refactoring above, you can test the rendering logic separately from the selection of which type of rendering to perform. Dividing methods in to smaller pieces nearly always allows you to isolate functionality more effectively.

And There's More...

I've only scratched the surface in this article. There is a lot more to be learned from natural language writing style. I highly recommend picking up a copy of The Elements of Style. Worst comes to worst, you'll greatly improve your writing of English; best case scenario, you'll pick up a lot of insightful tips on writing clearer and more readable code.


A Response to Dreamhost

Jan 12 2008

Dreamhost sure stirred things up with their article rant about rails deployment and performance issues. Their complaint is roughly that they are having to work too hard to support rails; it needs performance and deployment improvements. Dreamhost voiced all of these complaints on the company's blog.

As they put it...

What I do have personal knowledge of is how difficult it can be to get a Rails application up and running and to keep it running. DreamHost has over 10 years of experience running applications in most of the most popular web programming frameworks and Rails has and continues to be one of the most frustrating.
...the solution from the Rails community itself was quite honestly, stupid.
That suggestion shows either a complete lack of understanding of how web hosting works, or an utter disregard for the real world.
Ruby on Rails needs to be a helluva lot faster.
Ruby on Rails needs to more or less work in ANY environment.

Forgive me for chopping up their arguments. If you have the time, please read the article. These quotes don't quite do it justice; they serve merely to provide the tone of the piece.

Frankly, I think DHH responded well: rails core team is there to serve their own purposes. Ruby on Rails doesn't need to do anything, despite what a Dreamhost blogger might suggest. The people hacking on rails core don't target platforms like Dreamhost's. So, in fact, rails is not designed to run on shared hosting.

It's not just shared hosting, either. Dreamhost is trying to support rails on massively oversold servers. Configuring rails in a shared environment (particularly under apache) is difficult; configuring, and maintaining their servers to support rails probably costs Dreamhost a lot of money. Rails doesn't perform well in that environment, which probably costs them even more money in support calls from frustrated customers. So, their profit margins on rails service are likely narrowing.

Why is that the rails community's problem to solve? Dreamhost has a business challenge. Rails deployment isn't perfect — it has more than its fair share of problems; but, there are plenty of rails apps running just fine in production. This blog, a rails app, runs on a 20$ per month plan from slicehost. The identical app barely ran at Dreamhost. It's anecdotal evidence, sure, but the point is that rails deployment (at least on this scale) is far from impossible. Dreamhost just can't seem to squeeze it in to their oversold offerings. And, they want somebody else to fix the problem for them.

There are plenty of shared hosting offerings available that support rails nicely. Those companies don't seem to be having any trouble creating an environment that works. None of them have published angry articles pointing the finger at "the rails community". But, I digress.

If it were an individual complaining — a noobie who was having a tough time deploying his rails app on a server he could afford — then perhaps there would be a reason to look at this differently. But, Dreamhost is a corporation; they are simply "...looking to capitalize on a framework that's driving a lot of demand...", to borrow some words from DHH.

If this had been a PC manufacturer, complaining loudly (and rudely) that linux doesn't run on cheap enough hardware for them to sell PCs for 50$/each... If Linksys had posted a rant on their company blog, complaining that linux needed to be faster, because their routers weren't performing well enough... If IBM had posted a rant on their company blog, complaining that the linux community showed "...either a complete lack of understanding of how web hosting works, or an utter disregard for the real world."... Everybody would have said the same thing: so, fix it.

Plenty of businesses are capitalizing on open source technologies. But, part of the deal in the real world is that when something doesn't work right, you might have to fix it yourself; but you can, and that's part of what's so great about open source. Engine Yard just hired the entire rubinius team (and some people to hack merb, so I hear). Linux kernel developments are facilitated in large part by corporate sponsorship, bounties, etc. The system works, because companies can solve their own problems, while leveraging the work of countless others. That's how it works in the real world.


An Introduction to Ruby's Enumerable Module

Jan 05 2008

If you're still writing for loops, stop; there's a better way. Exactly why merits some examples.

[1, 2, 3].each { |number| puts number }

That's a pretty straightforward one. It says: with each element in this array, execute the given block. But, what if we wanted to do something more complicated, like determine whether there were any even numbers in the array?

[1, 2, 3].any? { |number| number % 2 == 0 } # => true
[1, 3, 5].any? { |number| number % 2 == 0 } # => false

The any? method says: are there any elements in the array for which this block evaluates to true? We might also want to know whether all? of the elements were even.

[2, 4, 6].all? { |number| number % 2 == 0 } # => true
[1, 2, 3].all? { |number| number % 2 == 0 } # => false

We can see that making good use of Enumerable methods produces highly readable code. Before we move on, there are a couple more methods that are worth demonstrating.

We've already seen how we can easily look inside of an array, using any?, and all?. Conveniently, Enumerable provides similar methods for extracting objects. What if we wanted, for example, to retrieve all of the even numbers.

[1, 2, 3, 4].select { |number| number % 2 == 0 } # => [2, 4]

...or, the first even number...

[1, 2, 3, 4].detect { |number| number % 2 == 0 } # => 2

Let's pick up the pace.

Putting the Pieces Together

If I was writing some blogging software, I might want to display recent activity in the administration area. With a big array of notification objects, I can use select to easily divide them up for display, based on recency.

today     = @notifications.select { |notification| notification.created_at > 1.day.ago.to_date }
yesterday = @notifications.select { |notification| notification.created_at < 1.day.ago.to_date && notification.created_at > 2.days.ago.to_date }
earlier   = @notifications.select { |notification| notification.created_at < 2.days.ago.to_date }

I'm actually doing something very similar to this in an app I'm working on. Since I love fat models, I created some helper methods on AR::Base. They look (something) like this:

class ActiveRecord::Base
  def today?
    created_at > 1.day.ago.to_date
  end
  
  def yesterday?
    created_at < 1.day.ago.to_date && created_at > 2.days.ago.to_date
  end
  
  def earlier?
    created_at < 2.days.ago.to_date
  end
end

So, now, we can greatly simplify our use of the select method, making it far clearer what we're up to.

today     = @notifications.select(&:today?)
yesterday = @notifications.select(&:yesterday?)
earlier   = @notifications.select(&:earlier?)

...wait, what? The ampersand operator, as described by the PickAxe book:

If the last argument to a method is preceded by an ampersand, Ruby assumes that it is a Proc object. It removes it from the parameter list, converts the Proc object into a block, and associates it with the method

But, a symbol isn't a Proc object. Luckily, ruby calls to_proc on the object to the right of the ampersand, in order to try and convert it to one. Symbol#to_proc is defined in ActiveSupport; it creates a block that calls the method named by the symbol on the object passed to it. So, for the above examples, the blocks send today?, yesterday?, or earlier?, respectively, to the each object that is yielded. Written out by hand, the expanded blocks would look like this:

today     = @notifications.select { |notification| notification.today?  }
yesterday = @notifications.select { |notification| notification.yesterday? }
earlier   = @notifications.select { |notification| notification.earlier? }

For additional to_proc coolness, it's worth mentioning Reg Braithwaite's String#to_proc (or get the code). I won't go on any further about that today, though.

Let's look at one last example — this time from real software. In order to add support for polymorphic, deep nesting in resource_controller, I had to write an algorithm that would determine which of the possible sets of parent resources were present at the invocation of a controller action. This is done by testing to see which of the params (parent_type_id) are present. So, if I say belongs_to [:project, :message], [:project, :ticket] in my comments controller, I need to determine: for which of those two possible sets are both necessary params present? Since belongs_to is just a simple accessor, the algorithm is easy to write.

belongs_to.detect { |set| set.all? { |parent_type| params["#{parent_type}_id".to_sym].nil? } }

Recap

Enumerable's biggest advantage over the for loop, as we've seen, is clarity. Using Enumerable's looping power tools, like any?, all?, and friends makes your code read semantically. Especially combined with Symbol#to_proc, code "...seems to describe what I want done instead of how I want the computer to do it.", to quote Raganwald.

Finally, in order to take your Enumerable usage to the next level, there are a few more methods you should have in your toolbox.

I'd also recommend keeping the Enumerable, and Array documentation bookmarked, so that you can quickly refer to them. As a bonus, most of these methods exist in prototype.js, too; just take a look at the documentation.