Refactoring with an apprentice

Posted 3 months back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

When I was part of thoughtbot’s apprentice.io program, I spent my days learning to code in a functional, maintainable and scalable way. In my first two weeks, refactoring with my mentor Anthony became one of my favorite exercises.

In my third week as an apprentice, we sat down to refactor a test I wrote for my breakable toy application. This is the process we followed:

# spec/features/teacher/add_an_assignment_spec.rb

require 'spec_helper'

feature 'teacher adding an assignment' do
  scenario 'can create an assignment with valid attributes' do
    teacher = create(:teacher)
    course1 = create(:course, name: 'Math', teacher: teacher)
    course2 = create(:course, name: 'Science', teacher: teacher)
    course3 = create(:course, name: 'History', teacher: teacher)
    course4 = create(:course, name: 'Quantum Physics', teacher: teacher)

    visit new_teacher_assignment_path(as: teacher)

    select 'Science', from: :assignment_course_id
    fill_in :assignment_name, with: 'Pop Quiz'
    fill_in :assignment_description, with: 'I hope you studied!'
    select '2014', from: :assignment_date_assigned_1i
    select 'January', from: :assignment_date_assigned_2i
    select '15', from: :assignment_date_assigned_3i
    select '2014', from: :assignment_date_due_1i
    select 'January', from: :assignment_date_due_2i
    select '17', from: :assignment_date_due_3i
    fill_in :assignment_points_possible, with: 100
    click_button I18n.t('helpers.submit.create', model: 'Assignment')

    expect(current_path).to eq(teacher_assignments_path)
    expect(page).to have_content('Course: Science')
    expect(page).to have_content('Name: Pop Quiz')
    expect(page).to have_content('Description: I hope you studied!')
    expect(page).to have_content('Date assigned: January 15, 2014')
    expect(page).to have_content('Date due: January 17, 2014')
    expect(page).to have_content('Points possible: 100')
  end
end

Check out this repo to follow along.

Key areas to improve on:

  • The section of code for filling out the form is not very legible especially the date fields.
  • The date_assigned and date_due fields are not named using Rails idioms.
  • There is a lot of repetition.
  • The code is not reusable.
  • It is important to abstract as many strings from your code as possible to make future changes less painful.

Where to begin?

Idiomatic date attributes

First we looked at some low hanging fruit. Anthony asked me, “when we use t.timestamps in a migration, what are the attribute names?” I knew immediately where he was going with this. Timestamps are named created_at and updated_at. The reason they are named with _at is because it gives developers context that says, “this is a DateTime.” Similarly, when naming Date attributes, the proper Rails idiom is _on.

This may seem like a small thing, but following conventions makes it much easier for other developers (including my future self) to read and derive context about my attributes without having to dig.

So, we changed date_assigned and date_due to assigned_on and due_on respectively:

select '2014', from: :assignment_assigned_on_1i
select 'January', from: :assignment_assigned_on_2i
select '15', from: :assignment_assigned_on_3i
select '2014', from: :assignment_due_on_1i
select 'January', from: :assignment_due_on_2i
select '17', from: :assignment_due_on_3i

Updated assertions to follow the same convention:

expect(page).to have_content('Assigned on: January 15, 2014')
expect(page).to have_content('Due on: January 17, 2014')

We check to make sure our test passes and make a commit.

Create what you need, and nothing more

This test creates 4 courses, so that a teacher must select which course the assignment belongs to. This could be done much more efficiently by using some simple Ruby. However, upon further consideration, having more than 1 course is not only unnecessary, but detrimental to our test because it writes unnecessary data to the database and increases run time.

teacher = create(:teacher)
course1 = create(:course, name: 'Math', teacher: teacher)
course2 = create(:course, name: 'Science', teacher: teacher)
course3 = create(:course, name: 'History', teacher: teacher)
course4 = create(:course, name: 'Quantum Physics', teacher: teacher)

becomes

teacher = create(:teacher)
create(:course, name: 'Science', teacher: teacher)

Again, we check to make sure the test still passes and commit.

Abstract clunky code to methods to increase readability

Anthony is always pushing me to write code so that it performs like it reads. Doing so ensures readability for myself and other developers, and forces us to make sure our objects and methods execute the intentions indicated by their name.

When Anthony isn’t around for conversations, I find pseudocoding helps organize my intentions:

# I want a method that:
#  fills out all attributes within my assignment form
#  selects a course from a dropdown list
#  fills in text fields with the appropriate attributes
#  selects dates for the appropriate attributes
#  submits my form
#  is readable and intention-revealing

The ugliest part of this test (in my opinion) is the way the date fields are selected. It takes 3 lines of code for each date because the form has a separate select for each Month, Day and Year. We can DRY (Don’t Repeat Yourself) this up by creating a method that will make these selections for us.

First, we write the method call:

select_date(:assignment, :assigned_on, 'January 15, 2014')
select_date(:assignment, :due_on, 'January 17, 2014')

When using form_for, form fields are all prefixed with the object they belong to (in this case, :assignment), so we pass that first. Second, we pass the form field we want to select. Third, we pass the date in a string.

Now we write the method:

def select_date(prefix, field, date)
  parsed_date = Date.parse(date)
  select parsed_date.year, from: :"#{ prefix }_#{ field }_1i"
  select parsed_date.strftime('%B'), from: :"#{ prefix }_#{ field }_2i"
  select parsed_date.day, from: :"#{ prefix }_#{ field }_3i"
end

To make extracting the Month, Day and Year from our string much easier, we convert them to a Date object and interpolate the form attributes using the prefix and field arguments.

The test is green, so we commit.

Extract parsing of Dates

We don’t love the local variable for parsing our date and there is an argument order dependency as well. So we extract the parsing of dates to local variables at the top of the test. We aren’t exactly sure what to do about the argument order dependency at this point, and assume this may be an issue with the next form field as well, so we put off that refactor for now.

assigned_on = Date.parse('January 15, 2014')
due_on = Date.parse('January 17, 2014')
...

select_date(:assignment, :assigned_on, assigned_on)
select_date(:assignment, :due_on, due_on)
...

def select_date(prefix, field, date)
  select date.year, from: :"#{ prefix }_#{ field }_1i"
  select date.strftime('%B'), from: :"#{ prefix }_#{ field }_2i"
  select date.day, from: :"#{ prefix }_#{ field }_3i"
end

We feel good about this refactor. Our code is still readable and introduction of the Date object will allow us to put the date in whatever format we like and still achieve the same result.

The test is green, so we commit.

Find similarities in your code

We have 3 text_field attributes being filled the exact same way. Following what we did with select_date, we can write a method that will fill in the text_field’s and will DRY up this duplication.

Again, we write the method call so that it reads as the code performs:

fill_in_text_field(:assignment, :name, 'Pop Quiz')
fill_in_text_field(:assignment, :description, 'I hope you studied!')
fill_in_text_field(:assignment, :points_possible, 100)

This isn’t much of an improvement. While we may have decreased a little bit of ‘noise’ and increased the legibility, we are accomplishing our task in the same number of lines and it is still repetitive. Stay tuned, we’re going somewhere with this.

def fill_in_text_field(prefix, field, value)
  fill_in "#{ prefix }_#{ field }", with: value
end

We are getting less out of this refactor than the last. We still have argument order dependencies and the code’s readability is much the same. However, notice the pattern forming between all the different form methods…

Our test is green, so we commit.

Be patient, go step-by-step

We have a lot of duplication. We are calling the methods select_date and fill_in_text_field multiple times each. We need to find a way (perhaps an object or method) to pass each form field type multiple arguments and iterate over them.

However, we need to make sure that all the form fields are essentially using the same format before we try to wrap them. We need to create a method for selecting our course. Write the method call:

select_from_dropdown(:assignment, :course_id, 'Science')

This may look a bit funny, selecting a course from a drop-down list with a field identifier of :course_id, but passing it the string 'Science' instead of an id. This is due to a little bit of form_for magic. When courses are created, each receives an id when persisted to the database. In our form, we want to be able to select courses that belong to a specific teacher. form_for allows us to display the names of the courses in the drop-down list, but once selected and submitted, the form actually sends the course_id that is required for our Assignment belongs_to :course association.

The method:

def select_from_dropdown(prefix, field, value)
  select value, from: :"#{ prefix }_#{ field }"
end

Now we can really see a pattern forming. Test is green, commit.

Abstract identical arguments using yield and wrapping method calls

The next refactor is a very small but integral step in making these other refactors worth while. What good are the select_from_dropdown, select_date and fill_in_text_field if we can’t use them every time we need to fill in another form?

In each of these method calls, we are passing a ‘prefix’ (in this case it is :assignment) which will always be present no matter what form you are filling out for a particular object. We can abstract this away by wrapping all of these method calls in another method that simply yields the prefix. We’ll call this method within_form(prefix, &block):

def within_form(prefix, &block)
  yield prefix
end

Update the method calls to fill in our form:

within_form(:assignment) do |prefix|
  select_from_dropdown(prefix, :course_id, 'Science')
  fill_in_text_field(prefix, :name, 'Pop Quiz')
  fill_in_text_field(prefix, :description, 'I hope you studied!')
  select_date(prefix, :assigned_on, assigned_on )
  select_date(prefix, :due_on, due_on )
  fill_in_text_field(prefix, :points_possible, 100)
end

All we are doing here is abstracting the object for the form into an argument, and supplying that argument to each method call with yeild.

But what if instead of yeilding our prefix, we were to yield an object back that understood the methods select_from_dropdown, select_date and fill_in_text_field? If that object understood our prefix, and these methods, we could use within_form for any object we need to fill in a form for.

Our test is green, so we commit.

When applicable, create a new object to handle a single responsibility

This next refactor has a lot of moving pieces. We want to create an object responsible for filling out all form fields. As always, write the method call and describe what you want it to perform:

within_form(:assignment) do |f|
  f.select_from_dropdown(course_id: 'Science')
  f.fill_in_text_field(name: 'Pop Quiz')
  f.fill_in_text_field(description: 'I hope you studied!')
  f.fill_in_text_field(points_possible: 100)
  f.select_date(assigned_on: assigned_on)
  f.select_date(due_on: due_on)
end

In order for within_form to perform properly we must update it to yield an object that understands each method responsible for filling out form fields.

def within_form(form_prefix, &block)
  completion_helper = FormCompletionHelper.new(form_prefix, self)
  yield completion_helper
end

By creating the FormCompletionHelper object, we have a place to put the select_from_dropdown, select_date and fill_in_text_field methods.

Each time within_form is called, a new instance of FormCompletionHelper is yielded. We call our form methods, and pass along the field and value arguments that each method requires:

class FormCompletionHelper
  delegate :select, :fill_in, to: :context

  def initialize(prefix, context)
    @prefix = prefix
    @context = context
  end

  def fill_in_text_field(field, value)
    fill_in :"#{ prefix }_#{ field }", with: value
  end

  def select_date(field, date)
    select date.year, from: :"#{ prefix }_#{ field }_1i"
    select date.strftime('%B'), from: :"#{ prefix }_#{ field }_2i"
    select date.day, from: :"#{ prefix }_#{ field }_3i"
  end

  def select_from_dropdown(field, value)
    select value, from: :"#{ prefix }_#{ field }"
  end

  private

  attr_reader :prefix, :context
end

This was a big refactor. By wrapping the methods select_from_dropdown, select_date and fill_in_text_field within the FormCompletionHelper class, their scope changes and they no longer have access to Capybara’s select and fill_in methods. In order to call these methods from FormCompletionHelper, we delegate to the test context (hence, choosing context for the name of this object). We do this by passing self as an argument to the within_form method and we delegate with the code:

delegate :select, :fill_in, to: :context

We also are able to remove prefix as an argument from each of our methods by defining a getter method for prefix:

attr_reader :prefix, :context

Our test is green, so we commit.

Remove duplication, through iteration

We are calling fill_in_text_field 3 times, select_date twice, and the click_button action that submits our form is reliant on ‘Assignment’ being passed as a string.

Let’s address the duplication:

within_form(:assignment) do |f|
  f.select_from_dropdown(course_id: 'Science')
  f.fill_in_text_fields(
    name: 'Pop Quiz',
    description: 'I hope you studied!',
    points_possible: 100
  )
  f.select_dates(
    assigned_on: assigned_on
    due_on: due_on,
  )
end
click_button I18n.t('helpers.submit.create', model: 'Assignment')

Notice that instead of passing multiple arguments, we now pass key: value pairs.

Now, we must adjust our methods to allow one or more fields:

def fill_in_text_field(options)
  options.each do |field, value|
    fill_in :"#{ prefix }_#{ field }", with: value
  end
end
alias :fill_in_text_fields :fill_in_text_field

def select_date(options)
  options.each do |field, date|
    select date.year, from: :"#{ prefix }_#{ field }_1i"
    select date.strftime('%B'), from: :"#{ prefix}_#{ field }_2i"
    select date.day, from: :"#{ prefix }_#{ field }_3i"
  end
end
alias :select_dates :select_date

def select_from_dropdown(options)
  options.each do |field, value|
    select value, from: :"#{ prefix }_#{ field }"
  end
end
alias :select_from_dropdowns :select_from_dropdown

In addition to adding iteration to each of these methods, we also create an alias for each method to allow singular or plural method calls.

alias :select_dates :select_date

The test is green, commit.

Complete abstractions

We know that in the context of a database backed object, form submit actions are only used to create or update the object. To make this submission dynamic we need to assign the model and stipulate whether the action is a create or update.

The method call as we want to see it perform:

def within_form(:assignments) do |f|
...
  f.submit(:create)
end

Implement #submit in FormCompletionHelper:

delegate :select, :fill_in, :click_button, to: :context
...
def submit(create_or_update)
  raise InvalidArgumentException unless [:create, :update].include?(create_or_update.to_sym)
  click_button I18n.t("helpers.submit.#{ create_or_update }", model: model_name)
end

private

def model_name
  prefix.to_s.capitalize
end

This refactor completes our ability to dynamically fill out forms. By abstracting the submit action to the FormCompletionHelper we are able to assign the model_name using our form_prefix. We also include an InvalidArgumentException to allow :create or :update arguments only.

Our test is green, so we commit.

Encapsulate behavior and keep code clean and organized through namespacing

Now that we’ve fully abstracted form completion, it doesn’t make much sense to leave #within_form or FormCompletionHelper in our spec/features/teacher/adding_an_assignment_spec.rb. We can move them to separate files, wrap them in a module, and include them in our RSpec configuration so that our teacher/adding_an_assignment_spec.rb will have access to them. A nice by-product of doing this is that any other feature specs that require a form to be filled out can now use the within_form method.

We move our FormCompletionHelper class to a new file called form_completion_helper.rb. The functionality that this class offers is only going to be used in feature spec files, so we place the file in the spec/support/features/ directory. We also namespace the class by wrapping it in a Features module.

# spec/support/features/form_completion_helper.rb

module Features
  class FormCompletionHelper
    delegate :select, :fill_in, :click_button, to: :context

    def initialize(prefix, context)
      @prefix = prefix
      @context = context
    end

    def fill_in_text_field(options)
      options.each do |field, value|
        fill_in :"#{ prefix }_#{ field }", with: value
      end
    end
    alias :fill_in_text_fields :fill_in_text_field

    def select_date(options)
      options.each do |field, date|
        select date.year, from: :"#{ prefix }_#{ field }_1i"
        select date.strftime('%B'), from: :"#{ prefix }_#{ field }_2i"
        select date.day, from: :"#{ prefix }_#{ field }_3i"
      end
    end
    alias :select_dates :select_date

    def select_from_dropdown(options)
      options.each do |field, value|
        select value, from: :"#{ prefix }_#{ field }"
      end
    end
    alias :select_from_dropdowns :select_from_dropdown

    def submit(create_or_update)
      raise InvalidArgumentException unless [:create, :update].include?(create_or_update.to_sym)
      click_button I18n.t("helpers.submit.#{create_or_update}", model: model_name)
    end

    private

    def model_name
      prefix.to_s.capitalize
    end

    attr_reader :prefix, :context
  end
end

We also created a form_helpers.rb file for our #within_form helper method. We also namespace this method in the Features and FormHelpers modules.

# spec/support/features/form_helpers.rb

module Features
  module FormHelpers
    def within_form(form_prefix, &block)
      completion_helper = FormCompletionHelper.new(form_prefix, self)
      yield completion_helper
    end
  end
end

The last step is to require these modules in /spec/spec_helper.rb.

RSpec.configure do |config|
  config.include Features
  config.include Features::FormHelpers
end

Our test is green, so we commit.

We’re done.

Next time, I might use the Formulaic gem. However, I find that exercises like this really help me understand the process of writing quality code.

What’s next?

If you found this post helpful, check out our refactoring screencast on Learn.

Also, check out this blog to take your test refactoring to the next level using I18n.

Our Problem with Boxen

Posted 3 months back at blah blah woof woof articles

Over a year ago, we started using Boxen at Icelab to manage our team’s development environments. It’s worked as advertised, but not well enough. I’m looking for something else.

Our problem with Boxen is that it contains hundreds of different components, all of which are changing, all the time. It needs constant tending. By the time a team is big enough to need something like Boxen, it’s paradoxically too small to look after it properly: to have someone whose job it is to be “Boxenmaster,” someone who knows how these intricate parts all interact and can run the regular clean installs needed to make sure that the experience is smooth for new people (we’ve found it typical for a functional Boxen setup to stay working over repeated updates, while clean installs end up failing). We need a tool that we can set up once for a project and then have it still work reliably 6 months later when we revisit the project for further work.

Boxen can be a trojan horse. If you don’t look after it properly, you risk creating two classes of developers within your team: those who were around to get Boxen working when you first rolled it out, now enjoying their nice functional development environments, and those who get started later, whose first experience in the team is one of frustration, non-productivity and a disheartening, unapproachable web of interconnected packages. And no one is safe: as soon as you want to upgrade that version of PHP, you could slip down there too.

So while Boxen can indeed work as manager of personal development environments, and while Puppet is a serious and capable configuration manager, my recommendation is not to commit to Boxen half-heartedly. In fact, you may not even need something so rigorous and complex if your team is still small. I’m looking into such alternatives right now. I’m not settled on anything yet, but it’ll likely involve virtual machines, and perhaps use Docker as a way to keep it lightweight while working on multiple projects at a time. Fig seems like it could be a good fit. I’ll keep you posted.

Episode #465 - May 16th, 2014

Posted 3 months back at Ruby5

A rich text editor that isn't awful, over one thousand free programming books, handle email subscriptions and track emails sent, super easy email unsubscribe, and a cheatsheet for OAuth exploits.

Listen to this episode on Ruby5

Sponsored by New Relic

New Relic is _the_ all-in-one web performance analytics product. It lets you manage and monitor web application performance, from the browser down to the line of code. With Real User Monitoring, New Relic users can see browser response times by geographical location of the user, or by browser type.
This episode is sponsored by New Relic

Quill

Quill is a modern rich text editor built for compatibility and extensibility. It was created by Jason Chen and Byron Milligan and open sourced by Salesforce.com.
Quill

Free Programming Books

A compilation of roughly 1,500 links to free programming-related resources.
Free Programming Books

OAuth Security Cheatsheet

This site describes common OAuth/Single Sign On/OpenID-related vulnerabilities.
OAuth Security Cheatsheet

Ahoy Email

Simple, powerful email tracking for Rails
Ahoy Email

Mailkick

Email subscriptions made easy
Mailkick

What to do when Stack Overflow is down?

Posted 3 months back at mir.aculo.us - Home

The Internet is awesome. Information at your fingertips and always-available help from people all over the world is one of humanity’s dreams come true. I’m not sure if the ancient philosophers included copy & pasting of code snippets in this dream, but it’s a fact of daily developer life.

It’s awesome, and it’s very convenient.

But this is not how you learn and become great at thinking for yourself, finding solutions for solving programming problems and most importantly how to be creative. Over-using sites like Stack Overflow will not make you a better developer, it will (probably) make you very good at clicking up-vote buttons and copy & pasting.

You owe it to your brain and future self that you try to find a solution first, and not give up just because something doesn’t work the first time you try it. Especially when you don’t feel comfortable or knowledgeable, because you’re working on a new project, with a new programming language or different development environment. Humans are built for exploration and understanding by doing. Your brain will reward you for discovering things. The rewards are higher as the problem is harder (for you) to solve.

That doesn’t mean to ban forums and answer sites from your bookmarks. You can and should share your discoveries and see how others solved similar problems. You’ll probably find that there’s (hope my cats won’t hear this) more than one way to skin a cat. Sharing will likely lead to new, better ways to tackle a specific problem, and this will benefit lots of people.

All because you spent 10 minutes thinking about a problem and not just copy & pasting the first answer that somewhat works.

Software Apprenticeship Podcast Episode 3 is Out

Posted 3 months back at Jake Scruggs

This week we start off by throwing Jonathan into the deep end of pool where he pairs with an experienced developer on a 10 year old Java project that is the core of our signature product: Backstop.  Of course the company is called Backstop Solutions and so, in order to avoid confusion, we gave the project a different name for internal use:  Fund Butter.  The mystery of how such a terrible thing came to pass is revealed in this very episode.

There’s no way we couldn’t discuss DHH’s Rails Conf declaration and blog post: “TDD is dead. Long live testing.” This, of course, leads to a discussion of our team’s test philosophy.

You can find it on iTunes (search for Software Apprenticeship Podcast), any podcast app’s search function, Google, this temp page: https://itunes.apple.com/us/podcast/software-apprenticeship-podcast/id868371146 or use the RSS feed directly if your into that sort of thing: http://softwareapprenticeship.libsyn.com/rss



Our panel (composed of Toby Tripp, Matt Pyra, Eric Johnson, Jonathan Howden, and I) meander through quite a few topics.  Here’s a breakdown by time of the various topics:

01:27 Backstop’s 2 day bug bash
02:00 The apprentice has to tackle a 10 year old Java program
06:22 “Everything needs to have an ID if you’re going to make it Hibernate-y” - Jake “super technical” Scruggs
08:21 Why we call Backstop “Fund Butter” within the company
10:50 The apprentice encounters Selenium
12:42 Troubles with regression/integration testing through the web browser.
13:43 “Unit Testing is Dead” - DHH 
20:00 Pairing all the time vs code review
21:51 Toby talks about the Hill Air Force Base pair programming study mentioned here: http://www.informit.com/articles/article.aspx?p=29410
26:40 The Wall of Awesome - Backstop’s way for employee’s to recognize and thank other employees
47:21 The anti-college movement
49:36 The “Expose your ignorance” apprenticeship pattern with examples/confessions from Jonathan, Jake, and Toby
51:14 The C3 project comes up with near 100% frequency when >= 2 die hard XP'ers are in the same room.

Episode #464 - May 13th, 2014

Posted 3 months back at Ruby5

In this episode we talk about new Ruby releases for versions 2.1.2 and 2.0.0-p48, Jekyll 2.0, Ruby core team disputing a CVE report, How Batched Queries work in Rails and FiniteMachine.

Listen to this episode on Ruby5

Sponsored by RailsLTS

With the release of Rails 4, support for Rails 2.3 and Rails 3.0 has ended. Security vulnerabilities are no longer patched for these versions. Rails LTS offers a solution for mission critical applications by providing security patches for old versions of Rails.
This episode is sponsored by RailsLTS

Ruby 2.1.2 and 2.0.0-p481

Late last week Ruby 2.1.2 was released alongside Ruby 2.0.0­-p481. Version 2.1.2 notably fixes a regression on the Hash#reject method.
Ruby 2.1.2 and 2.0.0-p481

Jekyll 2.0

Jekyll, the popular static site generator, released its 2.0 version last week. This new version is jam­-packed with highly­-requested features and bug fixes, thanks to the contribution of over 180 different developers.
Jekyll 2.0

Ruby CVE dispute

The Ruby core team is disputing an earlier CVE report. The CVE in question claimed that it was possible for an attacker to forge arbitrary root certificates by modifying the certificate’s signature. Apparently it’s simply a misunderstanding over the return value of the X509Certificate#verify method.
Ruby CVE dispute

How Batched Queries Work

Adam Sanderson wrote another article in his "Reading Rails" series titled 'How do Batched Queries Work', where he investigates Rails' find_each. The 'find_each' method is used to run queries when you don't want all the records instantiated at once.
How Batched Queries Work

FiniteMachine

FiniteMachine is a gem by Piotr Murach that provides a minimal finite state machine with a straightforward and intuitive syntax. The machine is event driven, with a focus on passing synchronous and asynchronous messages to trigger state transitions. It supports a natural DSL for declaring events, exceptions and callbacks.
FiniteMachine

Baseimage-docker 0.9.11 released

Posted 3 months back at Phusion Corporate Blog

Baseimage-docker is a special Docker image that is configured for correct use within Docker containers. It is Ubuntu, plus modifications for Docker-friendliness. You can use it as a base for your own Docker images. Learn more at the Github repository and the website, which explain in detail what the problems are with the stock Ubuntu base image, and why you should use baseimage-docker.

Changes in this release

  • Upgraded to Ubuntu 14.04 (Trusty). We will no longer release images based on 12.04.
    Thanks to contributions by mpeterson, Paul Jimenez, Santiago M. Mola and Kingdon Barrett.
  • Fixed a problem with my_init not correctly passing child processes’ exit status. Fixes GH-45.
  • When reading environment variables from /etc/container_environment, the trailing newline (if any) is ignored. This makes commands like this work, without unintentially adding a newline to the environment variable value:
    echo my_value > /etc/container_environment/FOO
    

    If you intended on adding a newline to the value, ensure you have two trailing newlines:

    echo -e "my_value\n" > /etc/container_environment/FOO
    
  • It was not possible to use docker run -e to override environment variables defined in /etc/container_environment. This has been fixed (GH-52). Thanks to Stuart Campbell for reporting this bug.

Using baseimage-docker

Please learn more at the README.

Baseimage-docker 0.9.10 released

Posted 3 months back at Phusion Corporate Blog

Baseimage-docker is a special Docker image that is configured for correct use within Docker containers. It is Ubuntu, plus modifications for Docker-friendliness. You can use it as a base for your own Docker images. Learn more at the Github repository and the website, which explain in detail what the problems are with the stock Ubuntu base image, and why you should use baseimage-docker.

Changes in this release

  • Upgraded to Ubuntu 14.04 (Trusty). We will no longer release images based on 12.04.
    Thanks to contributions by mpeterson, Paul Jimenez, Santiago M. Mola and Kingdon Barrett.
  • Fixed a problem with my_init not correctly passing child processes’ exit status. Fixes GH-45.
  • When reading environment variables from /etc/container_environment, the trailing newline (if any) is ignored. This makes commands like this work, without unintentially adding a newline to the environment variable value:
    echo my_value > /etc/container_environment/FOO
    

    If you intended on adding a newline to the value, ensure you have two trailing newlines:

    echo -e "my_value\n" > /etc/container_environment/FOO
    
  • It was not possible to use docker run -e to override environment variables defined in /etc/container_environment. This has been fixed (GH-52). Thanks to Stuart Campbell for reporting this bug.

Using baseimage-docker

Please learn more at the README.

The post Baseimage-docker 0.9.10 released appeared first on Phusion Corporate Blog.

Docker-friendly Vagrant boxes 2014-05-11 released

Posted 3 months back at Phusion Corporate Blog

Vagrant

We provide Vagrant base boxes that are based on Ubuntu 14.04 and 12.04, 64-bit. These boxes are specifically customized to work well with Docker. Please learn more at the website

The changes in version 2014-05-11 are:

  • The Ubuntu 12.04 boxes have been upgraded to kernel 3.13 (Trusty kernel). This is because even the updated VMWare Tools still occasionally caused kernel panics on kernel 3.8. In our tests, we’ve observed that VMWare Tools does not cause any kernel panics on kernel 3.13.
  • No changes in the Ubuntu 14.04 boxes.

Related resources: Github | Prebuilt boxes | Vagrant Cloud | Discussion forum | Twitter

Upgrade instructions for Vagrant >= 1.5 with Vagrant Cloud

Run:

vagrant box outdated

Upgrade instructions for Vagrant <= 1.4, or Vagrant >= 1.5 without Vagrant Cloud

Destroy your Vagrant VM:

vagrant destroy

Remove your existing base box:

# Vagrant >= 1.5
vagrant box remove phusion-open-ubuntu-12.04-amd64 --provider virtualbox
vagrant box remove phusion-open-ubuntu-12.04-amd64 --provider vmware_fusion

# Vagrant <= 1.4
vagrant box remove phusion-open-ubuntu-12.04-amd64 virtualbox
vagrant box remove phusion-open-ubuntu-12.04-amd64 vmware_fusion

Start your VM again. Vagrant will automatically download the latest version of the box.

vagrant up

Back to Basics: Regular Expressions

Posted 3 months back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

Regular expressions have been around since the early days of computer science. They gained widespread adoption with the introduction of Unix. A regular expression is a notation for describing sets of character strings. They are used to identify patterns within strings. There are many useful applications of this functionality, most notably string validations, find and replace, and pulling information out of strings.

Regular expressions are just strings themselves. Each character in a regular expression can either be part of a code that makes up a pattern to search for, or it can represent a letter, character or word itself. Let’s take a look at some examples.

Basics

First let’s look at an example of a regular expression that is made up of only actual characters and none of the special characters or patterns that generally make up regular expressions.

To get started let’s fire up irb and create our regular expression:

> regex = /back to basics/
 => /back to basics/

Notice we create a regular expression by entering a pattern between two front slashes. The pattern we’ve used here will only match strings that contain the stringi ‘back to basics’. Let’s use the match method, which gives us information about the first match it finds, to look at some examples of what matches and what doesn’t:

> regex.match('basics to back')
 => nil

We’re getting close, but nothing in this string matches our regular expression, so we get nil.

> regex.match('i enjoyback to basics')
 => <MatchData "back to basics">

After an unsuccessful attempt we have a match. Notice that our regular expression matched even though there are no spaces between the pattern and the words before it.

MatchData

The object returned from the RegularExpression object’s match method is of type MatchData. This object can tell us all sorts of things about a particular match. Let’s take a look at some of the information we can get about our match.

We can use the begin method to find out the offset of the beginning of our match in the original string:

> match = regex.match('i enjoyback to basics')
 => <MatchData "back to basics">

> match.begin(0)
 => 7

> 'i enjoyback to basics'[7]
 => "b"

The argument we send the method can be used to specify a capture, a concept which is covered below, within our match. In our above example begin tells us that the beginning of our match can be found at index 7 in our string. As we can see from the code above the 8th character in the string (at the 7th index in our string) is ‘b’ the first letter of our match.

Similarly we can get the index of the character following the end of our match using the end method:

> match.end(0)
 => 21

> 'i enjoyback to basics'[21]
 => nil

In this case we get nil since the end of our match is also the end of our string.

We can also use the to_s method to print our match:

> match.to_s
 => "back to basics"

Patterns

The regular expression’s real power becomes obvious when we introduce patterns. Let’s take a look at some examples.

Metacharacters

A metacharacter is any character that has a meaning within a regular expression. Let’s start with something simple, let’s say we want to find out if our string contains a number. This will require we use our first pattern the \d, which is a metacharacter that says we’re looking for any digit:

> string_to_match = 'back 2 basics'

> regex = /\d/
 => /\d/

> regex.match(string_to_match)
 => <MatchData "2">

Our regular expression matches the number 2 in our string.

Character Classes

Let’s say we wanted to find out if any of the letters from ‘k’ to ’s' were in our string. This will require we use a character class. A character class let’s us specify a list of characters or patterns that we’re looking for:

> string_to_match = 'i enjoy making stuff'

> regex = /[klmnopqrs]/
 => /[klmnopqrs]/

> regex.match(string_to_match)
 => <MatchData "n">

In this example we can see we entered all the letters of the alphabet we were interested in between the brackets and the first instance of any of those characters results in a match. We can simplify the above regular expression by using a range. This is done by entering two character or numbers separated by a -:

> string_to_match = 'i enjoy making stuff'

> regex = /[k-s]/
 => /[k-s]/

> regex.match(string_to_match)
 => <MatchData "n">

As expected, we get the same results with our simplified regular expression.

It’s also possible to invert a character class. This is done by adding a ^ to the beginning of the pattern. If we wanted to look for the first letter not in between ‘k’ and ’s' we would use the pattern /[^k-s]/:

> string_to_match = 'i enjoy making stuff'

> regex = /[^k-s]/
 => /[^k-s]/

> regex.match(string_to_match)
 => <MatchData "i">

Since ‘i’ isn’t in our range the first letter in our string meets the criteria our regular expression specified.

Another thing worth noting is the \d character we used above is an alias for the character class [0-9].

Modifiers

We have the ability to set a regular expression’s matching mode via modifiers. In Ruby this is done by appending characters after the regular expression pattern is defined. A particularly useful matching modifier is the case insensitive modifier i. Let’s take a look:

> string_to_match = 'BACK to BASICS'

> regex = /back to basics/i
 => /back to basics/i

> regex.match(string_to_match)
 => <MatchData "BACK to BASICS">

The regular expression matches our string in spite of the fact that the cases are clearly not the same. We’ll look at another common modifier later on in the blog.

Repetitions

Repetitions give us the ability to look for repeated patterns. We are given the ability to broadly search for that are repeating an indiscriminate number of time, or we can get as granular as the exact number of repetitions we’re looking for.

Let’s try to identify all the numbers in a string again:

> string_to_match = 'The Mavericks beat the Spurs by 21 in game two.'

> regex = /\d/
 => /\d/

> regex.match(string_to_match)
 => <MatchData "2">

Because we used only a single \d we only got the first digit, in this case ‘2’. What we’re actually looking for is the entire number, not just the first digit. We can fix this by modifying our pattern. We need to specify a pattern that will say find any group of contiguous digits. For this we can use the + metacharacter. This tells the regular expression engine to find one or more of the character or characters that match the previous pattern. Let’s take a look:

> string_to_match = 'The Mavericks beat the Spurs by 21 in game two.'

> regex = /\d+/
 => /\d+/

> regex.match(string_to_match)
 => <MatchData "21">

We could also look for an exact number of repetitions. Let’s say we only wanted to look for numbers between 100 and 999. One way we could do that would be using the {n} patern, where n indicates the number of repetitions we’re looking for:

> string_to_match = 'In 30 years the San Francisco Giants have had two 100 win seasons.'

> regex = /\d{3}/
 => /\d{3}/

> regex.match(string_to_match)
 => <MatchData "100">

Our pattern doesn’t match 30, but does match 100 because we told it only three repeating digit characters constituted a match.

Let’s look for words that are only longer than five characters. This will require a new metacharacter, the \w that matches any word character. Then we’ll use the {n,} pattern, which says look for n or more of the previous pattern:

> string_to_match = 'we are only looking for long words'

> regex = /\w{5,}/
 => /\w{5,}/

> regex.match(string_to_match)
 => <MatchData "looking">

You can also specify less than using this pattern {,m} and in between with this {n,m}.

Grouping

Grouping gives us the ability to combine several patterns into one single cohesive unit. This can be very useful when combined with repetitions. Earlier we looked at using repetitions with a single metacharacter \d, but rarely will that be enough to satisfy our needs. Let’s look at how we could define a more complex pattern we expect to see repeated.

Let’s look at how we might create a more complicated regular expression that matches phone numbers in several different formats. We’ll use groups and repetitions to do this:

> phone_format_one = '5125551234'
 => "5125551234"

> phone_format_two = '512.555.1234'
 => "512.555.1234"

> phone_format_three = '512-555-1234'
 => "512-555-1234"

regex = /(\d{3,4}[.-]{0,1}){3}/
 => /(\d{3,4}[\.-]{0,1}){3}/

> regex.match(phone_format_one)
 => <MatchData "5125551234" 1:"234">

> regex.match(phone_format_two)
 => <MatchData "512.555.1234" 1:"1234">

> regex.match(phone_format_three)
 => <MatchData "512-555-1234" 1:"1234">

We have successfully created our regular expression, but there is a lot going on there. Let’s break it down. First we define that our pattern will be made up of groups of three or four digits with this \d{3,4}. Next we indicate that we want to allow for ‘-’ or ‘.’ patterns (we have to escape the ‘.’ because this character is also a metacharacter that acts as a wild card), but that we don’t want to require these characters with this pattern [\.-]{0,1}. Finally we say we need three of this group of patterns by grouping the previous two patterns together and apply a repetition of three (\d{3,4}[.-]{0,1}){3}.

Lazy and Greedy

Regular expressions are by default greedy, which means they’ll find the largest possible match. Often that isn’t the behavior we’re looking for. When creating our patterns it’s possible to tell Ruby we’re looking for a lazy match, or the first possible match that satisfies our pattern.

Let’s look at an example. Let’s say we wanted to parse out the timestamp of a log entry. We’ll start out just trying to grab everything in between the square brackets that we know our log is configured to output the date in. In this pattern we’ll use a new metacharacter. The . is a wildcard in a regular expression:

> string_to_match = '[2014-05-09 10:10:14] An error occured in your application. Invalid input [foo] received.'

> regex = /\[.+\]/
 => /\[.+\]/

> regex.match(string_to_match)
 => <MatchData "[2014-05-09 10:10:14] An error occured in your application. Invalid input [foo]">

Instead of matching just the text in between the first two square brackets it grabbed everything between the first instance of an opening square bracket and the last instance of a closing square bracket. We can fix this by telling the regular expression to be lazy using the ? metacharacter. Let’s take another shot:

> string_to_match = '[2014-05-09 10:10:14] An error occured in your application. Invalid input [foo] received.'

> regex = /\[.+?\]/
 => /\[.+?\]/

> regex.match(string_to_match)
 => <MatchData "[2014-05-09 10:10:14]">

Notice that we added our ? after our repetition metacharacter. This tells the regular expression engine to keep looking for the next part of the pattern only until it finds a match; not until it finds the last match.

Assertions

Assertions are part of regular expressions that do not add any characters to a match. They just assert that certain patterns are present, or that a match occurs at a certain place within a string. There are two types of assertions, let’s take a closer look.

Anchors

The simplest type of assertion is an anchor. Anchors are metacharacters that let us specify positions in our patterns. The thing that makes these metacharacters different is they don’t match characters only positions.

Let’s look at how we can determine if a line starts with Back to Basics using the ^ anchor, which denotes the beginning of a line:

> multi_line_string_to_match = <<-STRING
"> I hope Back to Basics is fun to read.
"> Back to Basics is fun to write.
"> STRING
 => "I hope Back to Basics is fun to read.\nBack to Basics is fun to write.\n"

> regex = /^Back to Basics/
 => /^Back to Basics/

> regex.match(multi_line_string_to_match)
 => <MatchData "Back to Basics">

> match.begin(0)
 => 38

Looking at where our match begins we can see it’s the second instance of the string “Back to Basics” we’ve matched. Another thing to take note of is the ^ anchor doesn’t only match the beginning of a string, but the beginning of a line within a string.

There are many anchors available. I encourage you to review the Regex documentation and check out some of the others.

Lookarounds

The second type of assertion is called a lookaround. Lookarounds allow us to provide a pattern that must be matched in order for a regular expression to be satisified, but that will not be included in a successful match. These are called lookahead and lookbehind patterns.

Let’s say we had a comma delimited list of companies and the year they were founded. Let’s match the year that thoughtbot was founded. In this case we only want the year, we’re not interested in including the company in the match, but we’re only interestedin thougtbot, not the other two companies. To do this we’ll use a positive lookbehind. This means we’ll provide a pattern we expect to appear before the pattern we want to match.

> string_to_match = 'Dell: 1984, Apple: 1976, thoughtbot: 2003'

> regex = /(?<=.thoughtbot: )\d{4}/
 => /(?<=.thoughtbot: )\d{4}/

> regex.match(string_to_match)
 => <MatchData "2003">

Even though the pattern we use to assert the word thoughtbot preceeds our match appears in our regular expression it isn’t included in our match data. This is exactly the behavior we were looking for.

To specify a positive lookbehind we use the ?<=. If we wanted to use a negative lookbehind, meaning the match we want isn’t preceed by some particular text we would use ?<!=.

To do a positive lookahead we use ?=. A negative look ahead is achieved using ?!=.

Captures

Another useful tool is called a capture. This gives us the ability to match on a pattern, but only captures parts of the pattern that are of interest to us. We accomplish this by surrounding the pattern data we intend to capture with parenthesis, which is also how we specify a group. Let’s look at how we might pull the quantity and price for an item off of an invoice:

> string_to_match = 'Mac Book Pro - Quantity: 1 Price: 2000.00'

> regex = /[\w\s]+ - Quantity: (\d+) Price: ([\d\.]+)/
 => /[\w\s]+ - Quantity: (\d+) Price: ([\d\.]+)/ 

> match = regex.match(string_to_match)
 => <MatchData "Mac Book Pro - Quantity: 1 Price: 2000.00" 1:"1" 2:"2000.00"> 

> match[0]
 => "Mac Book Pro - Quantity: 1 Price: 2000.00" 

> match[1]
 => "1"

> match[2]
 => "2000.00"

Notice we have all the match data in an array. The first element is the actual match and the second two are our captures. We indicate we want something to be captured by surrounding it in parentheses.

We can make working with captures simpler by using what is called a named capture. Instead of using the match data array we can provide a name for each capture and access the values out of the match data as a hash of those names after the match has occurred. Let’s take a look:

> string_to_match = 'Mac Book Pro - Quantity: 1 Price: 2000.00'

> regex = /[\w\s]+ - Quantity: (?<quantity>\d+) Price: (?<price>[\d\.]+)/
 => /[\w\s]+ - Quantity: (?<quantity>\d+) Price: (?<price>[\d\.]+)/

> match = regex.match(string_to_match)
 => <MatchData "Mac Book Pro - Quantity: 1 Price: 2000.00" quantity:"1" price:"2000.00">

> match[:quantity]
 => "1"

> match[:price]
 => "2000.00"

Strings

There are also some useful functions that take advantage of regular expressions in the String class. Let’s take a look at some of the things we can do.

sub and gsub

The sub and gsub methods both allow us to provide a pattern and a string to replace instances of that pattern with. The difference between the two methods is that gsub will replace all instances of the pattern, while sub will only replace the first instance.

The gsub method gets its name from the fact that matching mode (discussed above) is set to global, which is accomplished using the modifier code g hence the name.

Let’s take a look at some examples.

> string_to_match = "My home number is 5125551234, so please call me at 5125551234."
 => "My home number is 5125551234, so please call me at 5125551234."

> string_to_match.sub(/5125551234/, '(512) 555-1234')
 => "My home number is (512) 555-1234, so please call me at 5125551234."

When we use sub we can see we still have one instance of our phone number that isn’t formatted. Let’s use gsub to fix it.

> string_to_match.gsub(/5125551234/, '(512) 555-1234')
 => "My home number is (512) 555-1234, so please call me at (512) 555-1234."

As expected gsub replaces both instances of our phone number.

While our previous example demonstrates the way the functions work it isn’t a particularly useful regular expression. If we were trying to format all the phone numbers in a large document we obviously couldn’t make our pattern the number in each case, so let’s revisit our example and see if we can make it more useful.

> string_to_match = "My home number is 5125554321. My office number is 5125559876."
 => "My home number is 5125554321. My office number is 5125559876." 

> string_to_match.gsub(/(?<area_code>\d{3})(?<exchange>\d{3})(?<subscriber>\d{4})/, '(\k<area_code>) \k<exchange>-\k<subscriber>')
 => "My home number is (512) 555-4321. My office number is (512) 555-9876."

Now our regular expression will format any phone number in our string. Notice that we take advantage of named captures in our regular expression and use them in our replacement by using \k.

scan

The scan method lets pull all reular expression matches out of a string. Let’s look at some examples.

> string_to_scan = "I've worked in TX and CA so far in my career."
 => "I've worked in TX and CA so far in my career." 

> string_to_scan.scan(/[A-Z]{2}/)
 => ["TX", "CA"]

Using a regular expression we pull out all the state codes in our string. One thing to keep in mind as you continue to learn is pay close attention to the assorted metacharacters available and how their meanings change depending context. Just in this introductory blog we saw multiple meaings for both the ^ and ? character and we didn’t even cover all of the possible meanings of even those two characters. Sorting out when each metacharacter means what is one of the more difficult parts of mastering regular expressions.

Regular expressions are one of the most powerful tools we have at our disposal with Ruby. Keep them in mind as you code and you’ll be surprised how often they can provide a nice clean solution to an otherwise daunting task!

What’s next?

If you found this useful, you might also enjoy:

Episode #463 - May 9th, 2014

Posted 3 months back at Ruby5

Untangline spaghetti code, opening the Atom source, better presenters with DumbDelegator, managing your OS X setup with osxc, an intro to Rails view caching, and the Eldritch async DSL all in this episode of the Ruby5!

Listen to this episode on Ruby5

Sponsored by New Relic

New Relic is _the_ all-in-one web performance analytics product. It lets you manage and monitor web application performance, from the browser down to the line of code. With Real User Monitoring, New Relic users can see browser response times by geographical location of the user, or by browser type.
This episode is sponsored by New Relic

Untangle Spaghetti Code

This article from Justin Weiss walks you through a refactoring that cleans up the code by reversing the caller and callee.
Untangle Spaghetti Code

Atom is OSS

The Atom editor is now open source!
Atom is OSS

DumbDelegator

The dumb_delegator gem is a delegator implementation specifically designed to work with Rails url helpers.
DumbDelegator

osxc

Tired of reinstalling things manually when you get a new machine? The osxc project will make this process a breeze for OS X machines!
osxc

Rails Caching

Want to start caching in Rails but aren't sure how to go about it? This two part blog post from Greg Molnar will tee you up!
Rails Caching

Eldritch

Eldritch is a DSL to make parallel programming easier in Ruby. Asynchronousness has never been easier!
Eldritch

Tips for Clojure Beginners

Posted 3 months back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

1. Learn the essentials with Clojure Koans.

Clojure Koans teaches you the basics of the language by providing a series of tests for you to turn green.

The topics and tests are chosen well, and the project’s vibe is pleasant (“calling a function is like giving it a hug with parentheses”).

Open a koan. Make it pass. Meditate. Enjoy enlightenment.

2. Move on to 4Clojure problems.

4Clojure is a great way to become familiar with Clojure’s many built-in functions.

Make sure to register an account and follow a handful of the Top Users. This will let you compare your solutions to theirs and be suitably mindblown.

A word of warning: 4Clojure tends to encourage code golf. Shorter is not always better.

For the longer problems, you may prefer to work in your editor. Check out offline-4clojure to get a local copy of the problems and tests.

3. Read a book or two.

Clojure Programming and The Joy of Clojure are both great places to start.

Clojure Programming is approachable, well-written, and no-nonsense. In particular, the examples are well-chosen and understandable.

The Joy of Clojure is also excellent, but takes more mental horsepower to get through. Its examples are perhaps more realistic, but thus more complicated and harder to follow.

4. Learn to develop interactively from your editor.

As a Rubyist, I’m used to running tests from my editor, and would never adopt a workflow that forced me to switch to the shell to run my tests. Additionally, I use the Spring pre-loader because rebooting the application every time I make a make a change and want to test it is painful. The ability to get test feedback quickly, and in the same place I’m writing them, contributes greatly to my flow and sense of happiness.

Despite this, when I want to interact with a running version of my application, it’s off to the Rails console I go. I write code “over here,” but interact with my running application “over there.”

Clojurians eschew this separation.

When writing Clojure, I can connect my editor to an instance of my running application that sticks around. When I change a function, I instruct that persistent application session to simply use the new function without restarting or reloading.

Further, when I want to see how the system behaves there’s no need to head off to some “over there” place. Instead, I can evaluate Clojure code in the context of my running application right from Vim, with results displayed wherever I might want them.

I had read descriptions of this development style and felt somewhat underwhelmed, but getting this set up and working really changed how much I enjoyed writing Clojure. Make sure you at least give this an honest shot before moving on.

  • Vim users: to get this experience, install Tim Pope’s fireplace.vim and read enough of the docs to learn how to eval code and open an in-editor REPL. Outdated resources might point you to VimClojure, but it is abandonware and should be avoided.

  • Emacs users: cider is what you’re looking for.

  • LightTable users: your editor does this out of the box! How enlightened of it. Check your docs for details, or just start on David Nolen’s interactive ClojureScript tutorial.

  • Users of other editors: you probably want to google something like [your-editor-name nrepl server].

5. Absorb Clojure’s philosophies and motivations with conference talks.

One of my favorite parts of the Clojure ecosystem is how many excellent conference talks are available. Three great examples, all from Rich Hickey, creator of Clojure:

  • Are We There Yet? - Rich asks whether OO as we practice it today is the best we can do. Spoiler: he thinks not. A great starting place to understand Clojure design motivations.

  • The Value of Values - Immutable data structures are a key element in Clojure’s design. This talk gives a great overview of their rationale and characteristics.

  • Simple Made Easy - Required viewing, if only because “complect” and “simple, in the Rich Hickey sense” are terms you’ll hear community members use often.

The above are some of my favorites, but I’ve been pleasantly surprised at the high quality of most Clojure talks I’ve watched, so don’t hestitate to dive into whatever looks interesting. For lots of options, check out the ClojureTV YouTube channel.

Bonus tip: I find I can watch most talks at 1.5x without a loss of comprehension. Enjoy that 40-minute talk in just 26!

6. Ask for help when stuck.

I’ve had good luck getting unstuck by asking for help in #clojure on freenode (IRC), reaching out to library authors directly on Twitter (thanks @swannodette, @weavejester, and @cemerick!), and the usual swearing/staring/source-diving that is sofware development.

7. Don’t panic.

Chances are, you’re coming to Clojure from an object-oriented languge with mutable data structures. Moving to a functional language with immutable data is a significant change of paradigm, and will take some getting used to. This is normal. Don’t feel bad if you struggle early on. I certainly did (and often still am)!

Episode #462 - May 6th, 2014

Posted 3 months back at Ruby5

Good news from the Ruby Core meeting, TDD debates galore, AdequateRecord, and some surprisingly uneventful code ping pong this week.

Listen to this episode on Ruby5

Sponsored by Pull Review

You want to ship it right instead of doing it again. But what could you clean while still meeting the deadline? PullReview reviews the Ruby code you just wrote and tells you what's wrong, why, and how to fix it - from style to security. Code, Spot, Fix, and Ship!
This episode is sponsored by Pull Review

Ruby Core Meeting

The Ruby Core Developer meeting took place in Japan and Terence Lee was kind enough to let us know what happened. Team Matz is considering accelerating the release schedule for Ruby patch releases. So that would be things like 2.1.1, and 2.1.2 as opposed to waiting for a 2.2 release. It would allow them to tackle bugs that cause dreaded segmentation faults much faster. To achieve this, Shibata Hiroshi & Koichi Sasada will work on a CI environment in order to make the release process easier. They also discussed removing commits that are not directly relevant to a patch release (or hotfix) before a the release goes out, probably in order to avoid potential regressions in those releases. By the way, since Ruby 2.1.0 was released, the core team announced that they would not release versions with patch­levels anymore. So no more obscure versions like 1.9.3­p545? Finally dear listeners, remember that feature suggestions for Ruby 2.2 are still being accepted so if you’ve ever wanted to give back to your favorite language, you should head over to bugs.ruby­lang.org right now.
Ruby Core Meeting

RailsConf Keynote & Videos

RailsConf was less than two weeks ago and the good people at Confreaks already have David Heinemeier Hansson’s keynote along with a handful of other talks available on their site. There’s another part of that talk that was a little less talked about: the part about David’s confession his inability to ever become a computer scientist. Although it was overshadowed by his knack for controversy, I think it was really interesting to hear such a prominent programmer — whatever you think of him — describe himself more as a software writer with affinities towards humanities instead of sciences.
RailsConf Keynote & Videos

TDD Counterpoints

So speaking of the TDD controversy, a number of prominent voices in the community have by now responded to his allegations that TDD for instance hinders design, is not necessary, etc. Robert Martin a.k.a Uncle Bob, was one of the first to respond with several blog posts actually. While deploring DHH’s rhetoric at first, he reiterated the benefits of TDD in a first post. As DHH continued aboard his TDD hate train, it was more like a blog ping pong than a code one. That’s about when it got interesting for me, right when Gary Bernhardt chimed in. On top of that yesterday, both Martin Fowler and Corey Haines joined in the merry battle of giants.
TDD Counterpoints

Duplication in Tests is Sometimes Good

Continuing down the testing path, this weekend Jakub Arnold published a short­yet­useful post entitled, “Duplication in Tests is Sometimes Good.”. I presume that you’re writing tests for your application or library. And I further presume you’re using a framework with before and after test hooks, like RSpec. People often use those hooks to clean up their test code, pulling out common setup and configuration. Is it possible that you can extract too much of that setup and configuration? Perhaps to the point of making your tests hard to understand? As Jakub shows, some duplication can be good. It’s not always bad to repeat ���yourself, especially if the repetition is easily updated with a find and replace.
Duplication in Tests is Sometimes Good

AdequateRecord

I think a much more important thing than dislike of TDD happened at RailsConf. I’m sad that not enough people have talked about Aaron Patterson’s Keynote. He spent quite a bit of time explaining the hard work that was put into speeding up ActiveRecord for the upcoming 4.2 release of Rails. He showed multiple benchmarks of the AdequateRecord branch and how in many ways it’s even faster than back in the Rails 2.3 days. So while the video for Aaron’s talk wasn’t available at the time of this recording, we highly recommend you watch it on Confreaks when it comes out. By the way, AdequateRecord has already been merged into rails/master on GitHub so you can already test it out if you like your edge really really bleedy.
AdequateRecord

Code Ping Pong with DHH - The Aftermath

And finally, to wrap up a TDDHH­filled episode, yesterday, Marcin Stecki published an article on the netguru blog describing some of the background for and aftermath from creating the Code Ping Pong with DHH site. In summation, the Rails 4 app was built on a whim, the source is available on GitHub, DHH didn’t know about it before hand, yet he did agree to respond to a handful of entries, DHH’s tweets brought several thousand eyes to the site, and ultimately Marcin was confused. As he put it, people poop on Rails all the time, but when presented with an avenue for presenting “bad code” to DHH for his thoughts, almost no one had any concrete examples. I think they got about 11 submissions ... and most of them weren’t even serious. Ultimately, only three entries were presented to David. Three submissions were presented to DHH... and David’s refactorings won the popular opinion vote for all three. Anyway, it is actually quite impressive to me that David volunteered his time for this, especially since he had nothing to do with its setup or concept. I appreciate that he gave his time and attention to what could’ve easily been seen as being silly and just ignored. So, thanks, David and Marcin!
Code Ping Pong with DHH - The Aftermath

Sponsored by Ruby5

Ruby5 is released Tuesday and Friday mornings. To stay informed about and active with this podcast, we encourage you to do one of the following:

Thank You for Listening to Ruby5

More new recruits

Posted 3 months back at RicRoberts :

Software engineer and web developer, Alex Lynham, is a Ruby enthusiast with particular expertise in front-end development but with ability throughout the stack. A speaker at NWRUG, he is also a fan of Python and JavaScript and divides his time between his love for programming and freelance music journalism.

Nicolas Terpolilli joins us from l’école Centrale de Lille for the summer. A software engineer, and devotee of Open Data, he’s a founder of rawdatahunter where he writes news and musings on Open Data.

And, on a contracting basis, we’ve been delighted to have Robin Gower with us since March. Robin has considerable software developing experience and is skilled at both front and back-end, development. And if that wasn’t enough, he’s also an economist and information analyst. Clever clogs.

You can see the rest of our team here.

Document Explicit Dependencies Through Tests

Posted 3 months back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

One of the purposes of writing tests is to provide living documentation of application’s code. Tests provide real examples of how a certain class or function is supposed to be used. Tests could also document the exact dependencies of the tested code.

The Problem

When Rails boots it loads most, if not all, of the application’s code, along with all of the dependencies (gems). Because of this, there is no need to require dependencies in individual files that contain application logic. When looking at the source of a specific class, it is hard to tell what external code it depends on. The test doesn’t help either.

A typical RSpec test usually looks something like this:

require 'spec_helper'

describe StyleGuide do
  # actual tests omitted
end

In the Rails community, it has become a de facto standard to require the default spec_helper (or an equivalent) in each test file. A typical spec/spec_helper.rb file ends up loading the whole Rails environment, requiring numerous helper files, and setting up various configuration options. All of that, en masse, is more than what any particular test file needs.

Certainly, integration and feature tests depend on the entire Rails environment. ActiveRecord model tests depend on the presence and configuration of a database. These are all good use cases for spec_helper. But what about unit tests that don’t require the database? When testing a plain old Ruby class, there might only be a few dependencies, if any.

The Solution

Being conscious about what must be required for a particular source file is a good thing. Instead of loading everything but the kitchen sink through the spec_helper, let’s specify the minimum dependencies inside of the test.

Here’s a revision of our code from above:

require 'basic_spec_helper'
require 'rubocop'
require 'app/models/style_guide'

describe StyleGuide do
  # actual tests omitted
end

This code states exactly what the tested class (app/models/style_guide.rb) depends on: the gem rubocop and basic_spec_helper.rb file.

The idea behind basic_spec_helper is that it’s very minimal, and that its sole purpose is to do a few convenience things. It should avoid becoming a junk drawer like spec_helper.

Here’s an example of a basic spec helper, extracted from Hound:

$LOAD_PATH << File.expand_path('../..', FILE)

require 'webmock/rspec'

RSpec.configure do |config|
  config.expect_with :rspec { |c| c.syntax = :expect }
  config.order = 'random'
end

This lightweight spec helper does just enough to enforce good practices and setup some configuration that should apply to all of the tests. Here’s the quick breakdown of what this spec helper is doing:

  1. Add the project root to the load path to allow requiring files starting at the project root.

    $LOAD_PATH << File.expand_path('../..', __FILE__)
    
  2. Requires webmock/rspec to ensure that external requests are not allowed.

    require 'webmock/rspec'
    
  3. Provides preferred RSpec configuration that all tests should adhere to.

    RSpec.configure do |config|
      config.expect_with :rspec { |c| c.syntax = :expect }
      config.order = 'random'
    end
    

Tests which might be part of a Rails application test suite, but don’t actually depend on Rails or ActiveRecord can now require this basic spec helper along with the essential gems and files. This causes each test to explicitly document dependencies of the tested code. Loading minimal dependencies during tests removes any magical coupling, helps with refactoring, saves time during debugging, and makes tests run faster.

What’s Next?

Want to learn more techniques about decoupling code away from Rails?