[SUMMARY] Refactoring (#75)

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
          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...