Refactoring Ruby

Hi all,

I have recently been refactoring some ruby code and was looking for
pointers or tips on how best to accomplish it. One problem that I have
had is finding all references to methods of a class that I was
refactoring. For example, if I have defined:

class Foo
def
# do something in here
end
end

and I wish to change it to:

class Foo
def get_with_index(index)
# do something slightly different
end
end

How do I find all occurances of in the code where objects of type Foo
are doing foo[index]? Searching for [] is no help because that is likely
all over the code. There are no type declarations to find instances of
foo. I can search for Foo.new and follow it through functions, etc but
that is often not simple.

Unit tests are helpful to see if my code still works, but even with them
I don’t feel completely secure that I have caught all instances.

Any ideas would be useful.

Thanks,

Steve Tuckner

How about adding some logging code to def [] and running your unit tests again.
Or you could just comment out def [] and see what complains when you’re running.

puts “called [] #{FILE}:#{LINE}”

Cheers,

  • alan
···

On Tue, Sep 10, 2002 at 11:28:43PM +0900, Steve Tuckner wrote:

How do I find all occurances of in the code where objects of type Foo are doing
foo[index]? Searching for [] is no help because that is likely all over the
code. There are no type declarations to find instances of foo. I can search for
Foo.new and follow it through functions, etc but that is often not simple.


Alan Chen
Digikata LLC

How about this:

class Foo
def
puts "Warning…[] called from #{caller}"
get_with_index(index)
end
def get_with_index(index)
#do something different
end
end

As it runs into code that uses the old method the warning will display
the file/line# where it was called from.

-rich

···

-----Original Message-----
From: Steve Tuckner [mailto:STUCKNER@MULTITECH.COM]
Sent: Tuesday, September 10, 2002 10:29 AM
To: ruby-talk ML
Subject: Refactoring Ruby

Hi all,

I have recently been refactoring some ruby code and was looking for
pointers or tips on how best to accomplish it. One problem that I have
had is finding all references to methods of a class that I was
refactoring. For example, if I have defined:

class Foo
def
# do something in here
end
end

and I wish to change it to:

class Foo
def get_with_index(index)
# do something slightly different
end
end

How do I find all occurances of in the code where objects of type Foo
are doing foo[index]? Searching for [] is no help because that is likely
all over the code. There are no type declarations to find instances of
foo. I can search for Foo.new and follow it through functions, etc but
that is often not simple.

Unit tests are helpful to see if my code still works, but even with them
I don’t feel completely secure that I have caught all instances.

Any ideas would be useful.

Thanks,

Steve Tuckner

Steve Tuckner STUCKNER@MULTITECH.COM wrote in message news:009701c258d6$4f2f49e0$6904a8c0@multitech.prv

How do I find all occurances of in the code where objects of type Foo
are doing foo[index]? Searching for [] is no help because that is likely
all over the code. There are no type declarations to find instances of
foo. I can search for Foo.new and follow it through functions, etc but
that is often not simple.

Unit tests are helpful to see if my code still works, but even with them
I don’t feel completely secure that I have caught all instances.

hmm. I tend to write extra unit tests in ruby, so that I can have
confidence that they walk over all branches of the code.

I wouldn’t worry to much about it if you deleted the [] method. You
know that it will crash hard, and the thrown NameError will tell you
exactly where, so if it does happen it won’t be a hard bug to fix.

~ Patrick

class Foo
def
puts "Warning…[] called from #{caller}"
get_with_index(index)
end
def get_with_index(index)
#do something different
end
end

Cool idea. You could probably take it a step further and have it
rewrite the code at that point. To do it right you would probably
have to have a parser that can parse ruby code. Here’s a dangerous
hack that can easily break code:

class Foo
def
puts “Warning…[] called from #{caller}”

  # now fix the offending line in the file.
  caller_file, caller_line = caller[0].split(":")
  caller_line = caller_line.to_i - 1  # each_with_index zero based
  File.open("#{caller_file}.new", "w") do |newfile|
    File.open(caller_file,"r").each_with_index do |line, lineno|
      if caller_line == lineno
        newfile.print "# XXX CHANGED FROM: #{line}"
        line.gsub!(/\[#{index}\]/,".get_with_index(#{index})")
      end
      newfile.print line
    end
  end
  # could be dangerous...
  File.rename(caller_file, "#{caller_file}}.old")
  File.rename("#{caller_file}.new", caller_file)

  get_with_index(index)
end

def get_with_index(index)
    #do something different
end

end

f = Foo.new

blah = f[10]

regards,
-joe