Refactoring (#75)


#1

Hopefully this quiz caused some of us to read Martin F.'s
Refactoring. I
know it did exactly that for me, though it has been on my want-to-read
list for
some time now. I’m half-way through it now and I can only recommend
everyone
reading this pick up a copy immediately.

Each of this week’s solutions came with its own write-up so there isn’t
a lot
left for me to dissect. Instead, I’ll take this chance to talk a little
about
the most interesting part of this exercise to me.

It’s my opinion that a large majority of the refactoring patterns were
designed
with the static languages in mind. I’m very intrigued by how a language
like
Ruby changes the game. Let’s me see if I can give some examples.

First, I mentioned in my write-up that part of my refactoring called for
making
a method abstract. After some thought, I decided that meant deleting
the method
in Ruby. (See my solution for the reasoning.)

Here’s another thought: many of the refactorings tell you to declare a
variable
as final, to ensure that it isn’t changing. What’s the Ruby equivalent
to that?
I don’t think we have one. We can #freeze the object, but that won’t
help us if
the variable is reassigned. I don’t see a good answer there.

But there are two sides to every coin and we have some nice advantages.
For
example, Extract Method talks a lot about how the local variables can
complicate
extraction, especially if many of them are changed by the extracted
code. This
is much less of an issue in Ruby though, since we can have the extracted
method
take a block and use the variables in there however we need. In fact,
this
means we can use Extract Method quite a bit more often, since the code
we pull
just needs to be close to similar and we can handle the differences in
the
block.

Dave B. was also thinking along these lines and went all the way to
introduce
some Ruby centric refactorings. Here’s an example:

Refactoring 2: Remove Unused Scope
/You have a begin...end block that introduces a scope that is unused./
*Remove the unused scope.*

Thus:

  def foo
    begin
      bar
    rescue
      baz
    end
  end

Becomes:

  def foo
    bar
  rescue
    baz
  end

I would love to see many more of these. Perhaps we could come up with a
Replace
Similar Methods with Metaprogrammed Definitions and a Convert a Family
of
Methods to a Single method_missing() Call recipes. Food for thought.

A big thank you to all who supported this deviation from our usual fun
and
games. I think Pat hit on a super important topic here and we would all
do well
to learn more about it.

Tomorrow, Matthew M. is back with a quiz about txet smnraiclbg…