Great example, thanks. See I would have had navigate_to take a screen
name as parameter without even thinking about it, due to my lack of
experience with method missing. Of course I use the Rails find_
methods all the time, figuring there must be some deep magic going on.
But it's really quite simple isn't it?
Thanks!
Steve
···
-----Original Message-----
From: Wilson Bilkovich [mailto:wilsonb@gmail.com]
Sent: Thursday, April 20, 2006 10:45 AM
To: ruby-talk ML
Subject: Re: [SUMMARY] Refactoring (#75)
This is from memory, because I don't have easy access to the code at the
moment.
I built a GUI application that automated various mainframe tasks for
users over TN3270E.
The particular mainframe in question had fairly tedious navigation
steps, and was broken out into separate 'screens', each of which had a
four-character name.
Long story short, I ended up making a method-missing handler for screen
navigation.
def method_missing(message, *args, &block)
if message =~ /navigate_to_(\w{4})/
x, y = find_prompt_coordinates
screen.put(x,y,$1)
screen.transmit
else
super
end
end
Which meant I could then say:
host.navigate_to_abcd
I could just as easily have made "navigate_to" take a screen name as a
parameter, but I thought this was easier to read. Maybe it's not the
best example.
--Wilson.
On 4/20/06, Molitor, Stephen L <Stephen.L.Molitor@erac.com> wrote:
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
endBecomes:
def foo
bar
rescue
baz
endI 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...