# Re: Thousands of words on Ruby

**URL:** <https://www.ruby-forum.com/t/re-thousands-of-words-on-ruby/67914>\
**Category:** Ruby\
**Created:** [September 7, 2006, 9:13pm UTC](https://www.ruby-forum.com/t/re-thousands-of-words-on-ruby/67914 "2006-09-07T21:13:53Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![MolitorS\_Stephen\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e480ec/32.png) [@MolitorS\_Stephen\_L](https://www.ruby-forum.com/u/MolitorS_Stephen_L)\
**Post date:** [September 7, 2006, 9:13pm UTC](https://www.ruby-forum.com/t/re-thousands-of-words-on-ruby/67914/1 "2006-09-07T21:13:53Z")

</div>

James,

What do you do for ‘rename method’ in TextMate? I’m aware of the search  
and replace in file feature but I was wondering if there was something  
better.

Nice write-up by the way. Ruby IDEs might not do all that Eclipse or  
NetBeans does for Java, but they’re not as primitive as Tim made them  
out to be! I was also surprised that he hadn’t tried Builder.

Steve

---

<div class="post-metadata">

**Author:** ![MolitorS\_Stephen\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e480ec/32.png) [@MolitorS\_Stephen\_L](https://www.ruby-forum.com/u/MolitorS_Stephen_L)\
**Post date:** [September 7, 2006, 10:12pm UTC](https://www.ruby-forum.com/t/re-thousands-of-words-on-ruby/67914/2 "2006-09-07T22:12:00Z")

</div>

On Sep 7, 2006, at 2:11 PM, Molitor, Stephen L wrote:

> What do you do for ‘rename method’ in TextMate? I’m aware of the  
> search  
> and replace in file feature but I was wondering if there was something  
> better.

First, let me admit this is the point I have the least ideal solution  
for and I am interested in a Ruby Refactoring library I can wrap in  
TextMate commands. Remember though, knowing everything about a Ruby  
script is all but impossible until runtime. Given that, such a  
library would likely function off of heuristics, and that’s about as  
accurate as…

I use TextMate’s Find in Project with a hand rolled regular  
expression. For your example of a method call I might try something  
like:

```
  Find: (\.|^[\t]*)method_name\b

```

Replace: $1new\_name

I can sometimes refine that a little depending on my knowledge of the  
project at hand. I always do a Find first, reality-check the  
matches, then Replace All. I find this works a very high percentage  
of the time, though I do make mistakes, of course.

Here are my solutions to the other points:

> ```
> There should be a background parser running all the time so  
> 
> ```
> 
> that you always know if you have syntax errors and can jump to them  
> with one click; it is so totally a waste of time for me to save,  
> then try to run, a file that the computer is in a position to know  
> won?t work.

I built a TextMate command scoped to Ruby source with a key  
equivalent of apple-S that takes the document as input and asks TM to  
save the current document when triggered. (This essentially  
overrides Save in Ruby files, performs the Save, and allows me to  
hook in additional functionality.

I feed the document to `ruby -c`. If it checks out, I display a  
Syntax OK tool tip (default output for this command). If errors are  
found, I use the exit\_codes.rb support library that ships with  
TextMate to switch the output to HTML and display hyperlinked-back-to-  
the-source error messages.

This command is an example in my upcoming book:

[http://www.pragmaticprogrammer.com/titles/textmate/index.html](http://www.pragmaticprogrammer.com/titles/textmate/index.html)

> ```
> I shouldn?t have to type the names of well-known methods,  
> 
> ```
> 
> like File.new or (anything).each, or type in closing parentheses or  
> the keyword end, or fill in more than a couple of characters of  
> begin/rescue/ensure structures; it is never correct for a human to  
> hit keys when a computer, in principle, could provide the input.

One word: snippets.

TextMate ships with all the snippets I have written for Ruby and then  
some.

> ```
> I should never have to scroll much; IDEs go to a lot of  
> 
> ```
> 
> trouble to make it trivial to jump from wherever to the source for  
> the method being called, or its docs, or the next compile error or  
> breakpoint, or variable declaration, or whatever. Scrolling back  
> and forth in a source-code file is just stupid.

Apple-T to zoom to the needed file, shift-apple-T to zoom to the  
needed method. Once you get use to how it matches names you can go  
anywhere in an instant:

1. apple-T
2. bit-return (takes me to test/functional/beta\_invite\_test.rb)
3. shift-apple-T
4. teir-return (takes me to test\_email\_is\_required)

> ```
> Unit testing should be part of the infrastructure. To create  
> 
> ```
> 
> a test, or run a test, or look at test results, you shouldn?t have  
> to hit more than one keystroke.

Apple-R to run a test file, or shift-apple-R to run just the current  
test. Use zentest to auto-generate the tests (you can wrap that in  
a TextMate command with about three lines of Ruby, if you like).

Hope this helps.

James Edward G. II

---

<div class="post-metadata">

**Author:** ![MolitorS\_Stephen\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e480ec/32.png) [@MolitorS\_Stephen\_L](https://www.ruby-forum.com/u/MolitorS_Stephen_L)\
**Post date:** [September 8, 2006, 2:48pm UTC](https://www.ruby-forum.com/t/re-thousands-of-words-on-ruby/67914/3 "2006-09-08T14:48:09Z")

</div>

On Sep 7, 2006, at 11:37 PM, Devin M. wrote:

> command TM to save?  
> The “Save” dropdown menu at the top of the Bundle Editor when you are  
> editing a command. 😉

James Edward G. II

---

<div class="post-metadata">

**Author:** ![MolitorS\_Stephen\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e480ec/32.png) [@MolitorS\_Stephen\_L](https://www.ruby-forum.com/u/MolitorS_Stephen_L)\
**Post date:** [September 8, 2006, 6:40am UTC](https://www.ruby-forum.com/t/re-thousands-of-words-on-ruby/67914/4 "2006-09-08T06:40:56Z")

</div>

> [http://www.pragmaticprogrammer.com/titles/textmate/index.html](http://www.pragmaticprogrammer.com/titles/textmate/index.html)  
> Err, oh. I take it that means it’d be too much to ask how you command TM  
> to save?

Devin  
(what’s the emoticon for “sad puppy face”?)

---

<div class="post-metadata">

**Author:** ![MolitorS\_Stephen\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e480ec/32.png) [@MolitorS\_Stephen\_L](https://www.ruby-forum.com/u/MolitorS_Stephen_L)\
**Post date:** [September 9, 2006, 5:20pm UTC](https://www.ruby-forum.com/t/re-thousands-of-words-on-ruby/67914/5 "2006-09-09T17:20:30Z")

</div>

On Sep 9, 2006, at 9:41 AM, Alex Y. wrote:

> Ok, so it’s a real bodge to try to rename a method before runtime.  
> What happens if we annotate the method to be renamed the next time  
> it’s run? We could run the script in question under an environment  
> not totally unlike xmp. The first thing it would do is alter the  
> source file according to the annotation. It would then add an  
> appropriate method\_missing to Object to do a rename in the original  
> source file whenever the method was called, and then load() the file.

And what happens if the execution never calls the given method, for  
whatever reason, or only reaches some of the places it is used?

James Edward G. II

---

<div class="post-metadata">

**Author:** ![MolitorS\_Stephen\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e480ec/32.png) [@MolitorS\_Stephen\_L](https://www.ruby-forum.com/u/MolitorS_Stephen_L)\
**Post date:** [September 9, 2006, 5:34pm UTC](https://www.ruby-forum.com/t/re-thousands-of-words-on-ruby/67914/6 "2006-09-09T17:34:31Z")

</div>

James Edward G. II wrote:

> And what happens if the execution never calls the given method, for  
> whatever reason, or only reaches some of the places it is used?

That’s why you run your test suite through it. You do have 100% line  
coverage, right? 🙂

---

<div class="post-metadata">

**Author:** ![MolitorS\_Stephen\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e480ec/32.png) [@MolitorS\_Stephen\_L](https://www.ruby-forum.com/u/MolitorS_Stephen_L)\
**Post date:** [September 9, 2006, 5:44pm UTC](https://www.ruby-forum.com/t/re-thousands-of-words-on-ruby/67914/7 "2006-09-09T17:44:32Z")

</div>

On Sep 9, 2006, at 10:33 AM, Alex Y. wrote:

> > And what happens if the execution never calls the given method,  
> > for whatever reason, or only reaches some of the places it is used?  
> > That’s why you run your test suite through it. You do have 100%  
> > line coverage, right? 🙂

Well it’s a clever idea. Show us the prototype. 😉

James Edward G. II

---

<div class="post-metadata">

**Author:** ![MolitorS\_Stephen\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e480ec/32.png) [@MolitorS\_Stephen\_L](https://www.ruby-forum.com/u/MolitorS_Stephen_L)\
**Post date:** [September 9, 2006, 7:44pm UTC](https://www.ruby-forum.com/t/re-thousands-of-words-on-ruby/67914/8 "2006-09-09T19:44:46Z")

</div>

James Edward G. II wrote:

> > > > source file whenever the method was called, and then load() the file.  
> > > > And what happens if the execution never calls the given method, for  
> > > > whatever reason, or only reaches some of the places it is used?  
> > > > That’s why you run your test suite through it. You do have 100% line  
> > > > coverage, right? 🙂
> 
> Well it’s a clever idea. Show us the prototype. 😉

Well, you asked for it 🙂 The usual provisos for prototype code apply:

$ cat rename\_method.rb  
$obj\_replacement\_table = {}  
class Object  
def method\_missing(sym, \*args, &block)  
if $obj\_replacement\_table.has\_key? sym.to\_s  
filename, line\_num = caller[0].split(’:’)[0,2]  
l = line\_num.to\_i - 1  
line\_arr = File.readlines(filename)  
line\_arr[l] = line\_arr[l].sub(sym.to\_s,  
$obj\_replacement\_table[sym.to\_s])  
File.open(filename, ‘wb’){|f| f.write line\_arr}  
self.send($obj\_replacement\_table[sym.to\_s].to\_sym, \*args, &block)  
end  
end  
end

def process\_file(filename)  
line\_arr = File.readlines(filename)  
line\_arr.each\_with\_index do |line,i|  
if line.chomp =~ /(\s+)def (\w+)(._)#\s_becomes\s+(\w+)/  
line\_arr[i] = “#{$1}def #{$4}#{$3}# was #{$2}\n”  
$obj\_replacement\_table[$2] = $4  
end  
end  
File.open(filename, ‘wb’){|f| f.write line\_arr }  
end

process\_file(ARGV[0])  
load(ARGV[0])

$ cat subject.rb  
class TestClass  
def my\_method(foo) # becomes my\_new\_method  
puts foo  
end  
end

def meth\_calling\_renamed(t)  
t.my\_method(‘Ok2’)  
end

t = TestClass.new  
t.my\_method(‘Ok1’)  
meth\_calling\_renamed(t)

$ ruby rename\_method.rb subject.rb  
Ok1  
Ok2

$ cat subject.rb  
class TestClass  
def my\_new\_method(foo) # was my\_method  
puts foo  
end  
end

def meth\_calling\_renamed(t)  
t.my\_new\_method(‘Ok2’)  
end

t = TestClass.new  
t.my\_new\_method(‘Ok1’)  
meth\_calling\_renamed(t)

There’s a _lot_ of scope for improvement in there, obviously, but that’s  
the general idea.

---

<div class="post-metadata">

**Author:** ![MolitorS\_Stephen\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e480ec/32.png) [@MolitorS\_Stephen\_L](https://www.ruby-forum.com/u/MolitorS_Stephen_L)\
**Post date:** [September 9, 2006, 4:42pm UTC](https://www.ruby-forum.com/t/re-thousands-of-words-on-ruby/67914/9 "2006-09-09T16:42:28Z")

</div>

James Edward G. II wrote:

> On Sep 7, 2006, at 2:11 PM, Molitor, Stephen L wrote:
> 
> > What do you do for ‘rename method’ in TextMate? I’m aware of the search  
> > and replace in file feature but I was wondering if there was something  
> > better.
> 
> First, let me admit this is the point I have the least ideal solution  
> for and I am interested in a Ruby Refactoring library I can wrap in  
> TextMate commands. Remember though, knowing everything about a Ruby  
> script is all but impossible until runtime.

Brainstorm just happened, so bear with me - this is straight off the top  
of my head, and may be stupid:

Ok, so it’s a real bodge to try to rename a method before runtime. What  
happens if we annotate the method to be renamed the next time it’s run?  
We could run the script in question under an environment not totally  
unlike xmp. The first thing it would do is alter the source file  
according to the annotation. It would then add an appropriate  
method\_missing to Object to do a rename in the original source file  
whenever the method was called, and then load() the file.

Good idea? Worth trying? Hideously flawed?
