The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
When describe'ing it ain't enough

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Brian Ford

Posts: 153
Nickname: brixen
Registered: Dec, 2005

Brian Ford is Rails developer with PLANET ARGON.
When describe'ing it ain't enough Posted: Mar 3, 2009 1:22 AM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Brian Ford.
Original Post: When describe'ing it ain't enough
Feed Title: def euler(x); cos(x) + i*sin(x); end
Feed URL: http://feeds.feedburner.com/defeulerxcosxisinxend
Feed Description: euler(PI) # => -1
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Brian Ford
Latest Posts From def euler(x); cos(x) + i*sin(x); end

Advertisement

One of the things I like about the RSpec syntax is that it packs a lot of information into a few concise, consistent constructs. It’s relatively easy to read through a spec file and pick out what I am looking for. The use of blocks both enable flexible execution strategies and provide simple containment boundaries.

Perhaps the most valuable aspect, though, is the ability to extend the RSpec syntax constructs easily and consistently. No need to grow a third arm here. In Rubinius, we recently encountered a situation needing some extra sauce when fixing our compiler specs.

A compiler can be thought of as something that chews up data in one form and spits it out in another, equivalent, form. Typically, these transformations from one form to another happen in a particular order. And there may be several of them from the very beginning to the very end of the compilation process.

To write specs for such a process, it would be nice to focus just on the forms of the data (that’s what we care about) with as little noise as possible about how they got there. Here’s what we have in Rubinius:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
describe "An And node" do
  relates "(a and b)" do
    parse do
      [:and, [:call, nil, :a, [:arglist]], [:call, nil, :b, [:arglist]]]
    end

    compile do |g|
      g.push :self
      g.send :a, 0, true
      g.dup

      lhs_true = g.new_label
      g.gif lhs_true

      g.pop
      g.push :self
      g.send :b, 0, true

      lhs_true.set!
    end
  end
end

The relates block introduces the Ruby source code and contains the blocks that show various intermediate forms. A single word like parse and compile encapsulates the process of generating that particular form, as well as concisely documenting the specs.

The format is sufficiently flexible to allow for other forms. For instance, ast for generating an AST directly from the parse tree rather than using the sexp as an intermediate form. Or llvm to emit LLVM IR directly from our compiler.

Another interesting aspect of this, it was possible with only a few custom extensions to MSpec. Recently, I had added custom options to the MSpec runner scripts to enable such things as our --gc-stats. I didn’t know how easy it would be to add something more extensive. Turns out it was pretty easy. You can check out the source in our spec/custom directory.

Read: When describe'ing it ain't enough

Topic: Free FXRuby Course Online at RubyLearning.org Previous Topic   Next Topic Topic: Ward Cunningham on the Debt Metaphor

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use