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
endTo 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 ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access