Building Flexible Interfaces
Heads up: you might start to feel a bit of déjà vu in this section. What we’ll cover here is basically a recap of what was discussed in Chapter 2, Designing Beautiful APIs, mixed in with a little dynamic help here and there. Though each step may seem fairly inconsequential, the end result is quite powerful.
When implementing a flexible domain-specific interface, the idea is
that we want to strip away as much boilerplate code as possible so that
every line expresses something meaningful in the context of our domain. We
also want to build up a vocabulary to work with, and express our intents
in that vocabulary as much as possible. A domain-specific interface puts
Ruby in the background: available when you need it, but not as
in-your-face as ordinary programmatic interfaces tend to be. An easy
comparison would be to look at the difference between some elementary
Test::Unit
code and its RSpec equivalent.[7]
First, we’ll look at the vanilla Test::Unit
code:
class NewAccountTest < Test::Unit def setup @account = Account.new end def test_must_start_with_a_zero_balance assert_equal Money.new(0, :dollars), @account.balance end end
To a Rubyist, this code might seem relatively clear, straightforward, and expressive. However, its defining characteristic is that it looks like any other Ruby code, with all the associated benefits and drawbacks. Others prefer a different approach, which you can clearly see in this RSpec code:
describe Account, " when first created" do ...
Get Ruby Best Practices now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.