James,
Great summary. Wish I had participated in the quiz!
I liked Dave Burt's 'Removed Unused Scope' example. Would you (or
someone else) care to give examples of 'Replace Similar Methods with
Metaprogrammed Definitions' and a 'Convert a Family of Methods to a
Single method_missing()'? I'm especially interested in the latter. I
know how method_missing works and I've seen its use in frameworks (like
Rails), but I've never actually written one myself.
I'm sure there are opportunities to use these Rubyesque type
refactorings in my code but I tend not to see them due to lack of
experience. One of the great things about the Refactoring book for me
was that it gave examples of things that I could easily relate to my own
application code. It sharpened my nose.
Thanks again for the quiz.
Steve
···
-----Original Message-----
From: Ruby Quiz [mailto:james@grayproductions.net]
Sent: Thursday, April 20, 2006 9:07 AM
To: ruby-talk ML
Subject: [SUMMARY] Refactoring (#75)
Hopefully this quiz caused some of us to read Martin Fowler'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 Burt 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 Moss is back with a quiz about txet smnraiclbg...