# \[QUIZ} Extract Method

**URL:** <https://www.ruby-forum.com/t/quiz-extract-method/57986>\
**Category:** Ruby\
**Created:** [April 17, 2006, 3:38pm UTC](https://www.ruby-forum.com/t/quiz-extract-method/57986 "2006-04-17T15:38:36Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![pat\_eyler](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/858c86/32.png) [@pat\_eyler](https://www.ruby-forum.com/u/pat_eyler)\
**Post date:** [April 17, 2006, 3:38pm UTC](https://www.ruby-forum.com/t/quiz-extract-method/57986/1 "2006-04-17T15:38:36Z")

</div>

James’ writeup was quite a bit nicer than mine, but I thought I should  
post  
a solution too, if I was going to suggest the quiz.

Refactoring Name: Extract Method

Original Code (taken from the checkr project):  
def process\_args(exp)  
@saw\_asgn = true  
args = []  
exp.length.times do  
element = exp.shift  
if element.kind\_of? Array  
args \<\< process(element)  
else  
args \<\< init\_var(element)  
end  
end  
s(:args,  
\*args)  
end

def process\_block(exp)  
unless exp[1] != [:nil]  
@errors \<\< “no-op in block”  
end  
args = []  
exp.length.times do  
element = exp.shift  
if element.kind\_of? Array  
args \<\< process(element)  
else  
args \<\< init\_var(element)  
end  
end  
s(:block,  
\*args)  
end

Explanation and mechanics:

process\_block was written by creating the new functionality (the  
unless block at the beginning) and copying the args building code  
from process\_args. This created a block of duplicate code that  
I didn’t want to maintain, so I extracted a method like this:

I created a new method, build\_sexp  
I moved the code from process\_block into it  
I replaced the code in process\_block with a call to build\_sexp  
I reran my test suite to verify that nothing broke[1]  
I replaced the original code in process\_args with a call to build\_sexp  
I reran my test suite to verify that nothing broke

New Code (ordered by method name):  
def build\_sexp(exp)  
args = []  
exp.length.times do  
element = exp.shift  
if element.kind\_of? Array  
args \<\< process(element)  
else  
args \<\< init\_var(element)  
end  
end  
args  
end

def process\_args(exp)  
@saw\_asgn = true  
args = build\_sexp(exp)  
s(:args,  
\*args)  
end

def process\_block(exp)  
unless exp[1] != [:nil]  
@errors \<\< “no-op in block”  
end

```
args = build_sexp(exp)
s(:block,
  *args)

```

end

This actually lead to a couple of other refactorings. We didn’t like  
the fact that build\_sexp did two things (emptied the original array,  
and processed each member of the new array), so we extracted another  
method. Then we realized that our two new methods were poorly named,  
so we performed Rename Method on both of them. we’re not sure we’ll  
use the code we ended up with, as it still hides some functionality  
that we might want to keep explicit, but it was a good exercise to  
go through.

–  
thanks,  
-pate
