Three part method

I find methods/functions decomposed into three parts really satisfying. Consider a typical xUnit test:

def test_grants_new_role
  # setup
  user = make_user
  new_role = make_new_role

  # behavior under test
  user.add_role(new_role)

  # assert results
  assert_equal [new_role], user.roles
end

Lately I’ve been structuring Rails controller similarly:

def create
  # Extract inputs/parameters from HTTP request
  person_params = params.require(:person).permit(:name, :age)

  # Invoke behavior encapsulated in a Plain(ish) Ruby object somewhere
  user = UserService.create_user(person_params)

  # Check the result and make some HTTP output
  if user.persisted?
    redirect_to user_path(user.id)
  else
    @user = user
    render :new
  end
end

Clojure even has the let form which encourages this style:

; annotated from clj-http
; https://github.com/dakrone/clj-http/blob/master/src/clj_http/util.clj
(defn gzip
  "Returns a gzip'd version of the given byte array."
  [b]
  (when b
    ; set the table
    (let [baos (ByteArrayOutputStream.)
          gos  (GZIPOutputStream. baos)]

      ; do the work and clean up
      (IOUtils/copy (ByteArrayInputStream. b) gos)
      (.close gos)

      ; produce a result
      (.toByteArray baos))))

I don’t think there’s anything inherently wrong if a method or function isn’t organized this way. But when I read code structured this way, it feels less like a bunch of random logic and more like a cohesive unit that someone put time into thinking through how someone might try to understand it later. The Rule of Three rules everything around us.

Adam Keys @therealadam