Posted about 5 hours back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home
If you’re a Ruby developer working with Rails, at some point you’re going to
need to work with JavaScript. While the two languages have many similarities,
the fundamental differences in their object models can be quite jarring.
CoffeeScript helps to provide a more Ruby-like syntax, but if you’re not careful
you can introduce bugs to your code in surprising ways.
Let’s look at an example. Let’s say we have an expensive operation, and need to
cache the result. In CoffeeScript, we might write the this code as:
class GiantRobot
smashCache: {}
smashInto: (other) =>
@smashCache[other] ||= @expensiveCalculations(other)
However, this code leads to a surprising problem when we start smashing things
together.
ralph = new GiantRobot()
voltron = new GiantRobot()
ralph.smashInto(optimusPrime) # => not cached
ralph.smashInto(optimusPrime) # => cached
voltron.smashInto(optimusPrime) # => cached?!
To see why this occurs, we need to take a look at how objects work in
JavaScript. Unlike Ruby, JavaScript has no concept of classes. Instead it
constructs its objects using prototypes. If you’re writing your code in
CoffeeScript, you can almost always ignore this fact, and write your code as if
you were in Ruby or Python. In this case, however, CoffeeScript is making our
problem less apparent, so let’s take a look at what this code looks like using
plain JavaScript.
function GiantRobot() {}
GiantRobot.prototype.smashCache = {};
GiantRobot.prototype.smashInto = function(other) {
if (!this.smashCache[other]) {
this.smashCache[other] = this.expensiveCalculations(other);
}
return this.smashCache[other];
};
Specifically, our problem stems from the fact that setting smashCache on the
prototype may not work the way you’d think.
How prototypes work
When we create ralph with, ralph technically has no smashCache property.
When we do this.smashCache, JavaScript looks for that property on ralph,
followed by ralph’s prototype, then ralph’s prototype’s prototype, and so forth
until it finds something that has the smashCache property.
JavaScript provides us a way to see this in action, using the hasOwnProperty
method.
ralph.hasOwnProperty('smashCache') # => false
GiantRobot.prototype.hasOwnProperty('smashCache') # => true
So when we call this.smashCache, we are always getting back
GiantRobot.prototype.smashCache, which means when we mutate it, we are
mutating the same instance of smashCache that is used by every instance of
GiantRobot. This is only an issue when we’re talking about arrays and objects.
ralph.smashCache = 'some value'
# Variable assignment sets the property directly on the instance
ralph.hasOwnProperty('smashCache') == true
Avoiding mutating the prototype
So how do we get around this? Ironically, the answer is simply to make our
original example look more like our Ruby code.
class GiantRobot
constructor: ->
@smashCache = {}
Now each instance will have it’s own separate smashCache, and all is well with the
world.
Backbone.js gotcha: Mutating the defaults object
A similar problem exists in Backbone.js when using the defaults object on your
models.
class RobotProfile extends Backbone.Model
defaults:
images: []
addImage: (newImage) ->
@get('images').push(newImage) # => Mutates a shared instance
The solution for this problem is even simpler. If we change the defaults
property to be a function that returns the same hash, Backbone will call it
every time a new instance is created.
class RobotProfile extends Backbone.Model
defaults: ->
images: []
Now our images array will no longer be shared across multiple instances, and we
can mutate to our heart’s content.
Written by Sean Griffin
Posted about 10 hours back at Ruby5
Easier rules for class structure, ProMotion for RubyMotion, JSON APIs in Rails 4, concurrency with Futuroscope, ActiveRecord help via Searchlight, and internationalization with haml-i18n-extractor.
Listen to this episode on Ruby5
This episode is sponsored by Heroku
Build better apps, faster. Spend your time building applications, not managing the servers that run them. Heroku is a Platform as a Service that adds simplicity to deploying, scaling and managing the infrastructure that runs applications. It removes barriers that slow the software development process, freeing you to put 100 percent of your energy into creating quality software.
Sandi Metz's Rules for Developers
Sandi Metz, author of Practical Object-Oriented Design in Ruby, has put together some simple rules of thumb regarding class and method composition. Caleb Thompson wrote up a blog article about them over at the Thoughtbot blog.
ProMotion
To make it even easier to build iOS apps in Ruby, Jamon Holmgren created ProMotion, a RubyMotion framework for abstracting the screen and navigation handling in a Ruby-like way. It makes it easy to work with things like UINavigationControllers, UITabBarControllers, and UIViewControllers.
JSON APIs with Rails 4
Emil Soman wrote up a blog article on how to write a tested, documented and versioned JSON API Using Rails 4.
Futuroscope
Josep Jaume Rey of Codegram wrote in to let us know about Futuroscope. It's their implementation of "futures", which let you easily handle processes in the background. You just wrap your long-running code in a block, and retrieve the result when you need it.
Searchlight
The Searchlight gem, which simplifies complex method chains. It works with ActiveRecord and ActionView out of the box. It also lets you set defaults and offers other shortcuts for interacting with Rails forms.
haml-i18n-extractor
This week Shai Rosenfeld released the haml-i18n-extractor gem, which is a command line tool that looks for certain strings in your haml templates that are likely to be internationalized. It replaces those strings with calls to the translate ("t") method, then it creates the proper yaml locale files for you.
Posted 1 day back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home
Episode 49: The psychology of work:
In this week’s episode, recorded at RailsConf 2013, Ben Orenstein is joined by Gregg Pollack and Nathaniel Bibler from EnvyLabs and codeschool.com. Gregg shares what he’s learned running his business, when not to be transparent, how to deal with compensation, and how the EnvyLabs compensation structure has changed over the years. Nathan, Gregg, and Ben also discuss Code School, yearly payments to a subscription, making courses effective, effective marketing, the effectiveness of mailing lists, community events, shared ownership, and much more.
Posted 2 days back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home
Leadership is often defined as having the ability to make others want to do what it is that you would like them to do. You want people to want to use your software, and often their first introduction will be through the README on the GitHub project.
There are of course components to a technical document that make it more effective. Describe what it is that your project makes easier. Provide code examples detailing how the use of the library. Document the installation process. These are the basic elements which define a README.
Creating a great face for your project, however, requires still more.
Don’t get lazy just because this is for developers
Technical writing is still writing, and need not be dry and boring. Just as if you were writing an essay or blog post, you should strive to grab the attention of your reader early. This can be easily accomplished with a well-written introductory paragraph. Use strong or emphasised text to give a short description of what the software does, such as “Receive emails in your Rails app”. You can also use an image which relates to the functionality of your library or alludes to some pun in the name.
Your readers will most likey view your README in a browser. Please keep that in mind when formatting its content. Put the name of the library in an <h1> at the beginning of the file. Categorize content using two or three levels of header beneath. Make use of emphasis to call out important words. Link to project pages for related libraries you mention. Link to Wikipedia, Wiktionary, even Urban Dictionary definitions for words of which a reader may not be familiar. Make amusing cultural references. Add links to related projects or services.
The code matters
Besides speaking English, your readers also understand code. Developers love to see code samples, and a few lines of syntax highlighted source are worth a thousand words. plataformatec/simple_form does an excellent job of providing code examples as well as explanations for nearly every setting and interface call. Besides being extremely greppable, simple_form’s README is the top Google hit for nearly all simple_form searches.
Be aware that sometimes the reason someone is visiting your project’s page is that they have a problem. If you know about persistent issues, such as resolving a functional dependency, call that out in a section of its own and provide a solution or workaround. Right in the README. Yeah. A great example of one such issue is thoughtbot/capybara-webkit’s dependency upon Qt. Because a gem cannot satisfy this dependency, thoughtbot have added a notice about installation issues to the README.
You are also encouraged to add “badges,” such as Travis CI’s
or Code Climate’s
to your README, but remember that they reflect on your project—a passing build with high quality code attracts developers to your library, while a failing master build can give them pause.
Written by Caleb Thompson.
Posted 4 days back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home
Back in January, newly-minted Ruby Hero Sandi Metz introduced her rules for developers in an episode of Ruby Rogues Book Club.
I encourage you to listen to the podcast or read over the transcript.
The day that the discussion of these rules started at thoughtbot, we were about to start a new project. While they may be targeted at less experienced developers, we thought that they could have interesting implications in the code we wrote. The team agreed to stick to Sandi’s rules for this new project.
The rules
<figure style="margin-left: auto; margin-right: auto; width: 570px;">

<figcaption style="text-align: center">
There are four rules.</figcaption></figure>
Here are the rules as we have them in our project’s technical guidelines document:
- Classes can be no longer than one hundred lines of code.
- Methods can be no longer than five lines of code.
- Pass no more than four parameters into a method. Hash options are parameters.
Controllers can instantiate only one object.
This has a couple of corollaries for views:
- Views can only know about one instance variable.
- Views should only send messages to that object
(
@object.collaborator.value is not allowed).
Break these rules
These are not rules, but guidelines. There should be no hard-and-fast rules in programming. Paraphrasing Sandi, “You should break these rules only if you have a good reason or your pair lets you.” Your pair or the person reviewing your code are the people who you should ask.
Think of this as rule zero. It is immutable.
100-line classes
Despite the now large number of private methods, keeping classes short has proven easy. It forces you consider what the single responsibility of your class is, and what should be extracted.
This applies to specs as well. In one case, we found a spec file ran over the limit which helped us realize we were testing too many features. We split the file into few more focused feature specs.
Finding this brought to light one of the difficulties, which is that Git diffs won’t necessarily show when you exceed 100 lines.
Five lines per method
Limiting methods to five lines per method is the most interesting rule.
We agreed on a fairly strict definition of a line: if, else, and end are all lines. So in an if block with two branches, each branch can only be one line. For example:
def validate_actor
if actor_type == 'Group'
user_must_belong_to_group
elsif actor_type == 'User'
user_must_be_the_same_as_actor
end
end
Five lines ensure that you NEVER get to use else and elsif.
Having only one line per branch urges you to use well-named private methods to get work done. Private methods are great documentation: Private methods need very clear names, which again force you to think about the content of the code you are extracting.
This is a good idea even if you don’t follow these other ideas.
Four method arguments
Rails is not designed to help us adhere to these rules. This rule particularly was challenging, especially in the views.
View helpers such as link_to or form_for can end up requiring a lot of parameters to work correctly. While we put some effort into not passing too many arguments, we fall back to Rule 0 and leave the parameters if we can’t find a better way to do it.
Only instantiate one object in the controller
This rule raised the most eyebrows before we started the experiment. Often one need more than one type of thing on a page. For example, a homepage may have both an activity feed and a notification counter.
We solved this using the Facade Pattern. It looks like this:
app/facades/dashboard.rb
class Dashboard
def initialize(user)
@user = user
end
def new_status
@new_status ||= Status.new
end
def statuses
Status.for(user)
end
def notifications
@notifications ||= user.notifications
end
private
attr_reader :user
end
app/controllers/dashboards_controller.rb
class DashboardsController < ApplicationController
before_filter :authorize
def show
@dashboard = Dashboard.new(current_user)
end
end
app/views/dashboards/show.html.erb
<%= render 'profile' %>
<%= render 'groups', groups: @dashboard.group %>
<%= render 'statuses/form', status: @dashboard.new_status %>
<%= render 'statuses', statuses: @dashboard.statuses %>
The Dashboard class provides a common interface for locating the user’s collaborator objects.
We pass the dashboard’s state to view partials and stop worrying about them.
When using instance variables in controller memoizations, we don’t count these toward the limit. We use the convention of prefixing unused variables with an underscore to make it clear what is meant to be used in a view:
def calculate
@result_of_expensive_calculation ||= SuperCalculator.get_started(thing)
end
Great success!
We recently concluded our experiment as a success and published results in our research newsletter.
The rules will remain part of the project conventions and have been incorporated into our best practices guide.
Written by Caleb Thompson.
Posted 4 days back at Ruby5
Today's episode covers a major release for minitest, some JSON standards work, a tutorial on tagging with ActiveRecord and Postgres (plus an arduino to trigger the spray paint can), a RubyMotion tutorial and a little thing called CoVim that will blow your mind.
Listen to this episode on Ruby5
This episode is 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.
Ruby Security Patches
Ruby 1.9.3-p429 and Ruby 2.0.0-p195 were released, to fix the security issue: Object taint bypassing in DL and Fiddle in Ruby (CVE-2013-2065)
minitest 5.0.0 released
Minitest had a major release with a really important change. MiniTest is now Minitest. Check out all the breacking details in the release notes.
jsonapi.org
jsonapi.org proposes a work-in-progress standard for JSON APIs. See also Nathan Esquenazi's Conforming to jsonapi.org format wiki.
Tagging With ActiveRecord and Postgres
Use PostgreSQL's array feature, along with ActiveRecord 4's array support to implement tagging in your Rails app.
RubyMotion Authentication Tutorial
Luca Tironi has written part one of a tutorial post on using Devise for RubyMotion Authentication which includes an example of using Clay Allsop's Formotion.
CoVim
Can you believe it! Real-time, multi-user collaboration in vim. CoVim is a plugin that makes it possible.
Posted 5 days back at Phusion Corporate Blog
BubbleConf: One day of ideas and action with the most vocal minds from tech, design, UX and business.

On october 12th 2012, we had the pleasure of co-organizing BubbleConf with our friends from Nedap and Teixido: the very first conference in Amsterdam aimed at designers, developers and entrepreneurs that was actually affordable for (bootstrapped) startups to attend[1]. We were blown away by the positive reception for our very first conference: 400 people put their trust in us in delivering an unforgettable day full of ideas and inspiration to apply to their own worklife. After reviewing the post conference survey, we were super excited to see so many people demanding a 2013 edition.
So without further ado, we’re pleased to announce that we’ll be doing a 2013 edition on September 27th 2013 so be sure to save the date! It will be held in Amsterdam once more, but we’ll be switching venues this time around to keep things exciting and fresh. The Tuschinski Theater had already set the bar quite high as we had been able to infer from our post conference survey so it took a while for us to find a venue that was at least as awesome. With the Beurs van Berlage, we think we have found just that:
© Beurs van Berlage Yakult Zaal
© Beurs van Berlage “Glazen Zaal”
The Beurs van Berlage will allow us to implement a few ideas we were unable to implement in our first edition due to time and space constraints. We look forward to sharing these ideas with you over the next couple of months leading up to BubbleConf! Many of these ideas align with what you’ve requested during last year’s survey, e.g. more opportunities to (better) meet up with one another and possibly showing each other their projects. Without saying too much just yet, please keep an eye out on our blog, twitter and newsletter to stay up to date about these developments.
© Beurs van Berlage terrace
© Beurs van Berlage cafe
Like last year, BubbleConf 2013 will be organized by Phusion and Nedap, and the design will be taken care of by Teixido. As for speakers, we’re once again working on securing some of the best in the business. We can already tell you that designers will be in for a huge treat. One might even say that this bubbleconf should be named bubbbleconf (typo intended
).
We started BubbleConf early this year by setting up a teaser site where people are able to purchase early believer tickets: these tickets are offered at a huge discount to people who were adventurous enough to buy them upfront without any beforehand knowledge of the date and location. We were super excited to see the first few tickets already sold this way, and want to thank these folks in particular for putting their blind-trust in us.
Now that the venue and date are known, the early believer discount is no longer applicable. The early bird discount however is still applicable so be sure to get your tickets asap to enjoy this discount.
Oh and one more thing: even though this is not yet set in stone, we’re working with Martijn Stegeman from the University of Amsterdam to see if we can make this into a two day event! More specifically, we’re working with him to see if we can kick off BubbleConf with an unconference on September 26th 2013. Details regarding tickets to this unconference will be made available in the near future.
The App University will bring together BubbleConf attendees as well as students who want to learn and teach more about programming, design or entrepreneurship. It will be targeted towards novices, intermediates and experts: we’re working hard on making it as accessible as possible to a broad range of people. So if you want to learn, or teach, keep an eye out for this one.
Well, that wraps it up for this week’s update. Be sure to keep an eye out for our blog, twitter and newsletter to stay in the loop!
[1] This is only possible due to the fact that we are personally sponsoring this conference for now. Like last year, all tickets are sold below cost price. Who knew that there are actually valid reasons as to why tickets are usually as expensive as they are?! Anyway, we’ll hope to get enough sponsors one day to cover the costs but at this time, we’re just super excited to have you over and contributing to the startup cause!
P.S. Interested in sponsoring this event? Please feel encouraged to contact us at info@bubbleconf.com! We’d love to talk!
Posted 5 days back at Jay Fields Thoughts
I've you've ever looked at the docs for clojure's for macro, then you probably know about the :let, :when, and :while modifiers. What you may not know is that those same modifiers are available in doseq.
I was recently working with some code that had the following form.
<script src="https://gist.github.com/jaycfields/5564037.js"></script>
Upon seeing this code, John Hume asked if I preferred it to a single doseq with multiple bindings. He sent over an example that looked similar to the following example.
<script src="https://gist.github.com/jaycfields/5564066.js"></script>
That was actually the first time that I'd seen multiple bindings in a doseq, and my immediate reaction was that I preferred the explicit simplicity of having multiple doseqs. However, I always have a preference for concise code, and I forced myself to starting using multiple bindings instead of multiple doseqs - and, unsurprisingly, I now prefer multiple bindings to multiple doseqs.
You might have noticed that the second version of the code slightly changes what's actually being done. In the original version the 'name' function is called once per 'id', and in the second version the 'name' function is called once per 'sub-id'. Calling name significantly more often isn't likely to have much impact on your program; however, if you were calling a more expensive function this change could have a negative impact. Luckily, (as I previously mentioned) doseq also provides support for :let.
The second example can be evolved to the following code - which also demonstrates that the let is only evaluated once per iteration.
<script src="https://gist.github.com/jaycfields/5564099.js"></script>
That's really the final version of the original code, but you can alter it slightly for experimentation purposes if you'd like. Let's assume we have another function we're calling in an additional let and it's expensive, it would be nice if that only occurred when an iteration was going to happen. It turns out, that's exactly what happens.
<script src="https://gist.github.com/jaycfields/5564144.js"></script>
Whether you prefer multiple bindings or multiple doseqs, it's probably a good idea to get comfortable reading both.
Posted 6 days back at Jay Fields Thoughts
I love using partial, but I dislike the length of the function name. There's a simple solution, define another function with a shorter name that simply calls (or is) partial. This is exactly what I did in the jry library.
<script src="http://gist-it.appspot.com/github/jaycfields/jry/blob/98c2e4cef3880041060ffec5e95d86096aaa4d1b/src/clojure/jry.clj?slice=0:3"></script>
I liked the use of % due to partial feeling similar to creating a function using #(), and % having a special meaning inside #(). I thought they tied well together. Unfortunately, there's an obvious problem, things would be very broken if you tried to use the '%' function in an anonymous function defined with #(). Somewhere along the way this issue caused me to stop using jry/%.
Using partial is great: it's part of the standard lib, and I don't need to explain it to anyone who joins my team or any future maintainers of the code I write. Still, I want something shorter, and I've always had a background thread looking for another shorter-than-partial solution. While recently contributing to emacs-live I found the solution I was looking for: clojure-mode font lock.
The following code can now be found in my emacs configuration.
<script src="http://gist-it.appspot.com/github/jaycfields/unplugged-pack/blob/a88a5dc2dfd905ff9de5fbac36976688fd4536dc/init.el?slice=11:16"></script>
This solution feels like the best of both worlds. My code still uses the function from the standard library, my colleagues still see a function they already know, and 'partial' only takes up one character space in my buffer. The image below is what you'll see if you put the above emacs-lisp in your config.
Posted 7 days back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home
We’ve been experimenting with Google Hangout for meetings such as daily standups with remote team members and interviews with remote candidates.
We concluded this experiment was a success.
It’s nice to have a recurring calendar invite to open, click “Join Hangout” and start talking.

Google Hangout is sometimes choppy over wifi. The settings need to change when we switch from laptop to monitor, so we often are without sound for a few seconds before changing the “FaceTime Camera (Built-In)” setting to “FaceTime HD Camera (Display)”.

We’ve noticed in longer meetings, we sometimes need to refresh the page if sound starts to get choppy, presumably to clear some buffering.
We’ve noticed during Hangouts that the sound captured by a Macbook Air’s internal microphones is often muffled. We generally have Macbook Pros for better performance of test suites, but there are a few of us who have Airs. We have started to fall back to phone calls for sound in those cases.
Overall, it’s always better to see someone’s face.
Written by Dan Croak.
Posted 7 days back at Ruby5
From multi to native json, JoyBox hits 1.0, ContextValidations and FormObjects, teaching kids at KidsCodeCamp, Plataformatec gems, tab navigation with Tabulous 2 and Git Real 2 online course.
Listen to this episode on Ruby5
This episode is sponsored by Envy Labs
Expert Ruby on Rails application development
RailsEdge using native json
Rails edge replaces the dependency on the ‘multi_json’ gem with Ruby 1.9’s native json.
JoyBox 1.0
JoyBox is a RubyMotion library for writing games using Cocoa2D and the Box2D physics engine.
ContextValidations
ContextValidations is a gem that allows you to decouple validations from ActiveRecord models.
FormObjects
The Panther Software blog explains how to use the Form Object pattern for a user registration process in Rails.
KidsCodeCamp
KidsCodeCamp is a free day long event for children with interactive classes for kids ages 7 to 16. They will go over Robotics, Information Technology, and even Minecraft, all in an easy to learn setting. It's taking place Sunday, August 25, right after the Madison Ruby conference.
Plataformatec gems
The Plataformatec guys announced a bunch of new gem updates for Rails 4 compatibility. This includes Devise, Simple Form, Show For, Mail Form, has_scope and Responders.
Tabulous 2
The Tabulous 2 gem provides all the functionality you need when using navigation tabs.
Git Real 2
Code School has just released Git Real 2. This is their third git course and it covers topics such as: Interactive Rebase, Stashing, Submodules, recovering lost commits and lost branches, as well as rewriting history. Check it out over on Code School if you want to solidify your git skills.
Posted 7 days back at Jay Fields Thoughts
I recently refactored some code that takes longs from two different sources to compute one value. The code originally stored the longs and called a function when all of the data arrived. The refactored version partials the data while it's incomplete and executes the partial'd function when all of the data is available. Below is a contrived example of what I'm taking about.
Let's pretend we need a function that will allow us to check whether or not another drink would make us legally drunk in New York City.
The code below stores the current bac and uses the value when legally-drunk? is called.
<script src="http://gist-it.appspot.com/github/jaycfields/Clojure--Testing-The-Creation-Of-A-Partial-Function/blob/master/src/clojure/original.clj"></script>
The following (passing) tests demonstrate that everything works as expected.
<script src="http://gist-it.appspot.com/github/jaycfields/Clojure--Testing-The-Creation-Of-A-Partial-Function/blob/master/test/expectations/original_expectations.clj"></script>
This code works without issue, but can also be refactored to store a partial'd function instead of the bac value. Why you would want to do such a thing is outside of the scope of this post, so we'll just assume this is a good refactoring. The code below no longer stores the bac value, and instead stores the pure-legally-drunk? function partial'd with the bac value.
<script src="http://gist-it.appspot.com/github/jaycfields/Clojure--Testing-The-Creation-Of-A-Partial-Function/blob/master/src/clojure/refactored.clj"></script>
Two of the three of the tests don't change; however, the test that was verifying the state is now broken.
<script src="http://gist-it.appspot.com/github/jaycfields/Clojure--Testing-The-Creation-Of-A-Partial-Function/blob/master/test/expectations/refactored_expectations.clj"></script>
note: The test output has been trimmed and reformatted to avoid horizontal scrolling.
In the output you can see that the test is failing as you'd expect, due to the change in what we're storing. What's broken is obvious, but there's not an obvious solution. Assuming you still want this state based test, how do you verify that you've partial'd the right function with the right value?
The solution is simple, but a bit tricky. As long as you don't find the redef too magical, the following solution allows you to easily verify the function that's being partial'd as well as the arguments.
<script src="http://gist-it.appspot.com/github/jaycfields/Clojure--Testing-The-Creation-Of-A-Partial-Function/blob/master/test/expectations/refactored_passing_expectations.clj"></script>
Those tests all pass, and should provide security that the legally-drunk? and update-bac functions are sufficiently tested. The pure-legally-drunk? function still needs to be tested, but that should be easy since it's a pure function.
Would you want this kind of test? I think that becomes a matter of context and personal preference. Given the various paths through the code the following tests should provide complete coverage.
<script src="http://gist-it.appspot.com/github/jaycfields/Clojure--Testing-The-Creation-Of-A-Partial-Function/blob/master/test/expectations/high_level_expectations.clj"></script>
The above tests make no assumptions about the implementation - they actually pass whether you :use the 'original namespace or the 'refactored namespace. Conversely, the following tests verify each function in isolation and a few of them are very much tied to the implementation.
<script src="http://gist-it.appspot.com/github/jaycfields/Clojure--Testing-The-Creation-Of-A-Partial-Function/blob/master/test/expectations/unit_level_expectations.clj"></script>
Both sets of tests would give me confidence that the code works as expected, so choosing which tests to use would become a matter of maintenance cost. I don't think there's anything special about these examples; I think they offer the traditional trade-offs between higher and lower level tests. A specific trade-off that stands out to me is identifying defect localization versus having to update the test when you update the code.
As I mentioned previously, the high-level-expectations work for both the 'original and the 'refactored namespaces. Being able to change the implementation without having to change the test is obviously an advantage of the high level tests. However, when things go wrong, the lower level tests provide better feedback for targeting the issue.
The following code is exactly the same as the code in refactored.clj, except it has a 1 character typo. (it's not necessary to spot the typo, the test output below will show you want it is)
<script src="http://gist-it.appspot.com/github/jaycfields/Clojure--Testing-The-Creation-Of-A-Partial-Function/blob/master/src/clojure/refactored_with_typo.clj"></script>
The high level tests give us the following feedback.
failure in (high_level_expectations.clj:14) : expectations.high-level-expectations
(expect
true
(with-redefs
[state (atom {})]
(update-bac 0.01)
(legally-drunk? 0.07)))
expected: true
was: false
There's not much in that failure report to point us in the right direction. The unit-level-expectations provide significantly more information, and the details that should make it immediately obvious where the typo is.
failure in (unit_level_expectations.clj:8) : expectations.unit-level-expectations
(expect
{:legally-drunk?* [pure-legally-drunk? 0.04]}
(with-redefs [state (atom {}) partial vector] (update-bac 0.04)))
expected: {:legally-drunk?* [#<refactored_with_typo$pure_legally_drunk_qmark_@621bedb0> 0.04]}
was: {:legally-drunk?** [#<refactored_with_typo$pure_legally_drunk_qmark_@621bedb0> 0.04]}
:legally-drunk?** with val [#<refactored_with_typo$pure_legally_drunk_qmark_@621bedb0> 0.04]
is in actual, but not in expected
:legally-drunk?* with val [#<refactored_with_typo$pure_legally_drunk_qmark_@621bedb0> 0.04]
is in expected, but not in actual
The above output points us directly to the extra asterisk in update-bac that caused the failure.
Still, I couldn't honestly tell you which of the above tests that I prefer. This specific example provides a situation where I think you could convincingly argue for either set of tests. However, as the code evolved I would likely choose one path or the other based on:
- how much 'setup' is required for always using high-level tests?
- how hard is it to guarantee integration using primarily unit-level tests?
In our examples the high level tests require redef'ing one bit of state. If that grew to a few pieces of state and/or a large increase in the complexity of the state, then I may be forced to move towards more unit-level tests. A rule of thumb I use: If a significant amount of the code within a test is setting up the test context, there's probably a smaller function and a set of associated tests waiting to be extracted.
By definition, the unit-level tests don't test the integration of the various functions. When I'm using unit-level tests, I'll often test the various code paths at the unit level and then have a happy-path high-level test that verifies integration of the various functions. My desire to have more high-level tests increases as the integration complexity increases, and at some point it makes sense to simply convert all of the tests to high-level tests.
If you constantly re-evaluate which tests will be more appropriate and switch when necessary, you'll definitely come out ahead in the long run.
Posted 8 days back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home
Episode 48: Barista imposter syndrome:
In this episode, recorded at RailsConf 2013, Ben Orenstein is joined by Jon Larkowski, closet hippie and developer at CareZone. Ben and Jon discuss being a closet hippie, transitioning from consulting to working on a startup/product team, ping-pong, paying attention to your habits and improving to your life, meditation, firewalling your attention, fostering a startup culture, imposter syndrome, podcasting, coffee, code review, guitar, and much more.
Posted 10 days back at Mike Clark

Posted 11 days back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home
Yeah, you know me.
We just pushed the latest update to Ruby Science, including five new chapters. Previous purchasers and Prime subscribers can grab the update on Learn.
New chapters this week discuss:
- Using the Single Responsibility Principle to create readable, reusable
classes.
- Applying the Open/Closed Principle to reduce churn and prevent breakage while
keeping objects easy to change.
- Applying the Dependency Inversion Principle to create flexible, reusable
objects.
- Using the Law of Demeter to prevent application dependencies from becoming a
tangled mess.
- Choosing Composition Over Inheritance to make simpler, more flexible software.
The book is a work in progress, and is currently 230 pages long. Your purchase gets you access to the current release of the book, all future updates, and the companion example application.
Get your copy of Ruby Science today.
Now Available For Free With Learn Prime
We recently launched a service to help subscribers become better developers, called Learn Prime.
For just $99/month, you get ongoing access to everything we teach, including books like Ruby Science. You’ll even get access to all our in-person and online workshops. Get access to exclusive subscriber content and use the forum to ask thoughtbot your toughest Ruby, Rails, and refactoring questions.
Subscribe now.
Written by Joe Ferris.