1
votes

The following is a section of exercise #5 (Silly Blocks) from Test-First.org which I'm trying to crack as I learn on my own, in preparation for a Ruby class.

Each exercise comes with an RSpec '_spec.rb' file and the user is expected to write a corresponding Ruby code '.rb' file, and continue to "rake it" until all the RSpec tests (examples) within are satisfied. At least that is my interpretation and I've been able to get through the first four exercises, however, the RSpec syntax in this exercise has me stumped. (Unfortunately, I'm not only fairly new to coding, I'm definitely very new to RSpes and I haven't been able to find a good newbie-grade intro to RSpec/TDD online).

Thus, I'm hoping a resident RSpec expert might help. Basically, I'd like to know what exactly is the following RSpec syntax telling me to write for code?

require "silly_blocks"

describe "some silly block functions" do

  describe "reverser" do
    it "reverses the string returned by the default block" do
      result = reverser do
        "hello"
      end
      result.should == "olleh"
    end
...

I assumed that I'm to write a method called 'reverser' which accepts a string argument, and returns the sting reversed, such as:

def reverser(string)
  return string.reverse
end 

Alas, that is clearly not correct - the rake fails miserably:

some silly block functions
  reverser
    reverses the string returned by the default block (FAILED - 1)

Failures:

  1) some silly block functions reverser reverses the string returned by the def
ault block
     Failure/Error: result = reverser do
     ArgumentError:
       wrong number of arguments (0 for 1)
     # ./05_silly_blocks/silly_blocks.rb:3:in `reverser'
     # ./05_silly_blocks/silly_blocks_spec.rb:15:in `block (3 levels) in <top (r
equired)>' 

I suspect it has something to do with passing "default code blocks" but I'm not sure how to structure that. There are many more methods to write in this exercise, however, if I can get some clarity on the initial one, I think I can work out the rest!

Major thanks, Danke sehr, Muchas gracias!! :)

1

1 Answers

5
votes

As far as I know, since this method takes a block and does something with it, you need to define the method to take a block, rather than an argument. So to enable the method to do this:

reverser do
  "hello"
end

You would write it something like:

def reverser
  yield.reverse
end

or:

def reverser(&block)
  block.call.reverse
end

Now the above methods will work when a block is passed to it: reverser { "hello" }, but not when an argument is used: reverser("hello").