# Smarter creation of redunant methods

**URL:** <https://www.ruby-forum.com/t/smarter-creation-of-redunant-methods/50462>\
**Category:** Ruby\
**Created:** [December 16, 2005, 4:45pm UTC](https://www.ruby-forum.com/t/smarter-creation-of-redunant-methods/50462 "2005-12-16T16:45:14Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Caleb\_T](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/977dab/32.png) [@Caleb\_T](https://www.ruby-forum.com/u/Caleb_T)\
**Post date:** [December 16, 2005, 4:45pm UTC](https://www.ruby-forum.com/t/smarter-creation-of-redunant-methods/50462/1 "2005-12-16T16:45:14Z")

</div>

I have some methods in a class that look like this:

def h\_coil(chan)  
raise NoDataError if @h\_coils[chan].nil?  
@h\_coils[chan]  
end

def i\_coil(chan)  
raise NoDataError if @i\_coils[chan].nil?  
@i\_coils[chan]  
end

and so on and so forth…

I’ve been refactoring a bit to cut down on the redunancy in the code,  
and  
I’m wondering your thoughts on the best way of doing this, considering  
that all methods have the same “signature”.

Is define\_method the smartest way?

# pseudo code off the top of my head, probably has errors:

def create\_coil\_method(name)  
define\_method(name) do |chan|  
iv = ("@" + name.to\_s + “s”).to\_sym  
val = instance\_variable\_get(iv)  
raise NoDataError if val.nil?  
val[chan]  
end  
end

create\_coil\_method(:h\_coil)  
create\_coil\_method(:i\_coil)  
…

Thanks,  
Caleb

---

<div class="post-metadata">

**Author:** ![Caleb\_T](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/977dab/32.png) [@Caleb\_T](https://www.ruby-forum.com/u/Caleb_T)\
**Post date:** [December 16, 2005, 5:03pm UTC](https://www.ruby-forum.com/t/smarter-creation-of-redunant-methods/50462/2 "2005-12-16T17:03:23Z")

</div>

Caleb T. wrote:

> end
> 
> and so on and so forth…
> 
> I’ve been refactoring a bit to cut down on the redunancy in the code,  
> and I’m wondering your thoughts on the best way of doing this,  
> considering that all methods have the same “signature”.
> 
> Is define\_method the smartest way?

You are recreating functionality that’s already there (assuming coils  
collections are arrays or hashes):

> > h={1=\>2}  
> > =\> {1=\>2}
> 
> > h.fetch 1  
> > =\> 2
> 
> > h.fetch 2  
> > IndexError: key not found  
> > from (irb):7:in `fetch’  
> > from (irb):7  
> > from :0
> 
> > a=[1]  
> > =\> [1]
> 
> > a.fetch 0  
> > =\> 1
> 
> > a.fetch 1  
> > IndexError: index 1 out of array  
> > from (irb):16:in `fetch’  
> > from (irb):16  
> > from :0

IMHO it’s not worth while to use meta programming in this case but YMMV.  
_If_ you use meta programming then I’d probably use a way that makes  
sure  
the member is there, properly initialized and the getter defined. I’d  
probably create a module whose initialize will create member variables  
and  
which when included will define the create\_coil for the including  
class…

> create\_coil\_method(:h\_coil)  
> create\_coil\_method(:i\_coil)  
> …

Of course you can combine both techniques and save the exception  
throwing  
part.

Kind regards

```
robert
```

---

<div class="post-metadata">

**Author:** ![Caleb\_T](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/977dab/32.png) [@Caleb\_T](https://www.ruby-forum.com/u/Caleb_T)\
**Post date:** [December 16, 2005, 5:21pm UTC](https://www.ruby-forum.com/t/smarter-creation-of-redunant-methods/50462/3 "2005-12-16T17:21:29Z")

</div>

On Sat, 17 Dec 2005, Caleb T. wrote:

> end
> 
> create\_coil\_method(:i\_coil)  
> you can certainly use metaprogramming here, but you could accomplish the  
> same  
> effect with far less code:

```
 harp:~ > cat a.rb
 class Coil
   class NoDataError < StandardError; end

   attr "coils"

   def initialize
     @coils =
       Hash::new{|h,k| h[k] = Hash::new{|h,k| raise NoDataError, 

```

“chan=#{ k }”}}  
end  
end

```
 coil = Coil::new
 chan = 1
 coil.coils["z"][chan] = 42

 p coil.coils["z"][chan]

 p coil.coils["x"][chan]

 harp:~ > ruby a.rb
 42
 a.rb:8:in `initialize': chan=1 (Coil::NoDataError)
         from a.rb:18

```

regards.

-a

---

<div class="post-metadata">

**Author:** ![Caleb\_T](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/977dab/32.png) [@Caleb\_T](https://www.ruby-forum.com/u/Caleb_T)\
**Post date:** [December 16, 2005, 6:30pm UTC](https://www.ruby-forum.com/t/smarter-creation-of-redunant-methods/50462/4 "2005-12-16T18:30:57Z")

</div>

On Sat, 17 Dec 2005, Caleb T. wrote:

> > you can certainly use metaprogramming here, but you could accomplish the  
> > same  
> > effect with far less code:
> 
> My issue is that I’ve got other methods in the class that use these  
> particular instance variables, and instead of refactoring all of them in  
> one fell swoop I’m trying to go in smaller chunks. Mostly because I’m  
> working on the “production” system (long story), so if break anything I  
> need to be able to roll it back quickly.

then something like

class Coil  
class Error \< StandardError; end

```
 class << self
   def coil_attr *list
     list.flatten.each do |a|
       module_eval <<-code
         def #{ a }_coil chan
           @#{ a }_coil[chan] or raise Error, "chan=\#{ chan }"
         end
       code
     end
   end
 end

 coil_attr %w( a b c x y z )

```

end

hth.

-a

---

<div class="post-metadata">

**Author:** ![Caleb\_T](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/977dab/32.png) [@Caleb\_T](https://www.ruby-forum.com/u/Caleb_T)\
**Post date:** [December 16, 2005, 9:59pm UTC](https://www.ruby-forum.com/t/smarter-creation-of-redunant-methods/50462/5 "2005-12-16T21:59:54Z")

</div>

Thanks - these are some good ideas I hadn’t thought of using before!

Caleb

---

<div class="post-metadata">

**Author:** ![Caleb\_T](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/977dab/32.png) [@Caleb\_T](https://www.ruby-forum.com/u/Caleb_T)\
**Post date:** [December 16, 2005, 6:06pm UTC](https://www.ruby-forum.com/t/smarter-creation-of-redunant-methods/50462/6 "2005-12-16T18:06:48Z")

</div>

> you can certainly use metaprogramming here, but you could accomplish the  
> same  
> effect with far less code:

My issue is that I’ve got other methods in the class that use these  
particular instance variables, and instead of refactoring all of them in  
one fell swoop I’m trying to go in smaller chunks. Mostly because I’m  
working on the “production” system (long story), so if break anything I  
need to be able to roll it back quickly.
