Josh Thompson     about     archive     turing     office hours

Mythical Creatures: Refactoring wizard.rb

Today we’re refactoring some code.

I find it extremely fruitful when others look over my code and help me clean it up. Quite a few Turing students have told me that the process of refactoring their own code with the help of someone who knows a bit more than them has been super helpful.

This is an exercise from Turing School’s ruby-exercises repository.

Specifically, we’re refactoring a solution that makes this test pass.

How to get the maximum value from this exercise

So far, I’ve found it most helpful to have my own code refactored. I wish I could help every single person who might read this post refactor their own code.

But I cannot.

But here’s the thing - when you’re working, you’ll often not be refactoring your own code either. It’s most likely you’ll be reading (and updating) code that someone else wrote.

Or you’ll be nestling in new code and new features alongside existing code and existing features.

So it’s useful to get practice reading other people’s code, and being able to work with it.

Video Walk-through

Sometimes video walk-throughs are helpful, so I put one together. It is 7 minutes long, and covers useful material.

Copy-paste this code into your editor and run the tests:

# ruby-exercises/mythical-creatures/wizard.rb
class Wizard
  attr_reader :name
  def initialize(name, bearded: false)
    @name = name
    @rested = 0
  end
  def bearded?
    if name == "Ben"
      true
    else
      false
    end
  end
  def incantation(saying)
    "sudo " + saying
  end
  def rested?
    if @rested >= 3
      false
    else
      true
    end
  end
  def cast
    @rested += 1
    "MAGIC MISSILE!"
  end
end

The tests should pass.

We’re going to cover a few things:

  • Guard Clauses
  • Default variables
  • Running just a single test from a test file instead of the whole thing
  • Sometimes simple things go wrong and are deeply frustrating

Guard Clauses

Here’s the guard clauses I mention: guard clauses (thechrisoshow.com)

Default variables

the test wizard are bearded by default implies that in the initialization method, we should set bearded equal to true, rather than false.

Run just a specific test in a test file (Minitest)

Sometimes it’s helpful to run just a single test in a test file, rather than the whole thing.

Here’s the format:

ruby something_test.rb --name=/a-string-that-matches-something-in-the-test-you-want-to-run/

instead of --name=/abc/, you can use -n=/abc. I’ll often append the string zzz to the test I want to run, then append -n/zzz/ to the test running command. (With rspec you can identify test by line number.)

Things go so, so wrong

The video walk-through was my second time recording the video, because I’d wandered so much in my explanations in the first video.

Then, mid-way through the video, I closed the terminal window, CD’d into the wrong directory, and got a bunch of errors. I got it fixed, then fat-fingered my way back into closing the terminal. I was super frustrated.

I’m ostensibly a “professional”, in that I get paid to “develop software”, but I thought it a useful reminder that we all do things that are frustrating and cause us to waste time. When you do this yourself, don’t worry about it to much. Our entire craft is hard. Reality has a surprising amount of detail and it’s annoying when we get bit by that detail.

Here’s the final version:

class Wizard
  attr_reader :name, :bearded, :rested, :spell_counter
  def initialize(name, bearded: true)
    @name = name
    @rested = true
    @bearded = bearded
    @spell_counter = 0
  end
  
  def bearded?
    bearded
  end
  
  def incantation(saying)
    "sudo " + saying
  end
  
  def rested?
    return false if spell_counter >= 3 # this is a "guard clause", sorta
    rested
  end
  
  def cast
    @spell_counter += 1
    "MAGIC MISSILE!"
  end
end

Are you a software developer who:

And wants to do all this in the most time-efficient way possible?

Great. Punch in your email:

Of course, you don't have to be a software developer to subscribe. It's easy to unsubscribe at any point. 😉