# Dispatching when function name is stated as a symbol

**URL:** <https://www.ruby-forum.com/t/dispatching-when-function-name-is-stated-as-a-symbol/113460>\
**Category:** Ruby\
**Created:** [August 31, 2007, 10:18am UTC](https://www.ruby-forum.com/t/dispatching-when-function-name-is-stated-as-a-symbol/113460 "2007-08-31T10:18:50Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![ronaldfischer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/67e7ee/32.png) [@ronaldfischer](https://www.ruby-forum.com/u/ronaldfischer)\
**Post date:** [August 31, 2007, 10:18am UTC](https://www.ruby-forum.com/t/dispatching-when-function-name-is-stated-as-a-symbol/113460/1 "2007-08-31T10:18:50Z")

</div>

Can someone point out an elegant way to solve the following problem?

I have a module with a function f and additional functions g1, g2, …,  
which basically looks like this:

module M  
def f(&cb)  
…  
x=cb.call  
# DO SOMETHING … see below  
end  
def g1(a,b,c)  
…  
end  
def g2(d,e)  
…  
end

# etc

end

The DO SOMETHING part looks like this: The proc object being called  
is supposed to return an array, where the first element is a symbol  
corresponding to one of the function names g1, g2 …, and the  
remaining array elements corresponding to the parameters of this  
function. Hence, if  
x=cb.call  
causes x to contain [:g2, 25, ‘dummy’], I would like to execute  
g2(25,‘dummy’)

I have not found a convincing way of doing this. Of course I can  
use a big case … end on the function names (ugly). I can turn  
the symbol :g2 into a string ‘g2’, marshal the arguments and put  
together a string containing the function call (even uglier).  
I also thought about using a hash of proc object (the keys being  
the symbols, the values being the procedures), kind of

{:g1 =\> proc {|a,b,c] g1(a,b,c)}, :g2 =\> proc {|d,e| g2(d,e)  
},…}[x[0]].  
call(\*x[1…-1])

but this looks like tremendous overkill too. Is there a simpler  
way of doing it?

## Ronald

Ronald F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
Phone: +49-89-452133-162

---

<div class="post-metadata">

**Author:** ![ronaldfischer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/67e7ee/32.png) [@ronaldfischer](https://www.ruby-forum.com/u/ronaldfischer)\
**Post date:** [August 31, 2007, 10:36am UTC](https://www.ruby-forum.com/t/dispatching-when-function-name-is-stated-as-a-symbol/113460/2 "2007-08-31T10:36:52Z")

</div>

On 8/31/07, Ronald F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> end  
> is supposed to return an array, where the first element is a symbol  
> corresponding to one of the function names g1, g2 …, and the  
> remaining array elements corresponding to the parameters of this  
> function. Hence, if  
> x=cb.call  
> causes x to contain [:g2, 25, ‘dummy’], I would like to execute  
> g2(25,‘dummy’)
> 
> I have not found a convincing way of doing this.

Would this work for you?

def f(&cb)  
x=cb.call  
name = x[0]  
args = x[1…-1]  
send(name, \*args);  
end

def g1(a,b,c)  
puts “g1: #{a}, #{b}, #{c}”  
end

def g2(d,e)  
puts “g1: #{a}, #{b}, #{c}”  
end

irb(main):017:0\> f {[:g1, 1, 2, 3]}  
g1: 1, 2, 3  
=\> nil  
irb(main):018:0\> f {[:g2, 1, 2, 3]}  
g2: 1, 2, 3  
=\> nil

Hope this helps,

Jesus.

---

<div class="post-metadata">

**Author:** ![ronaldfischer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/67e7ee/32.png) [@ronaldfischer](https://www.ruby-forum.com/u/ronaldfischer)\
**Post date:** [August 31, 2007, 10:39am UTC](https://www.ruby-forum.com/t/dispatching-when-function-name-is-stated-as-a-symbol/113460/3 "2007-08-31T10:39:52Z")

</div>

On 8/31/07, Jesús Gabriel y Galán [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> On 8/31/07, Ronald F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> puts "g1: #{a}, #{b}, #{c}"
> 
> ```
> 
> end
> 
> def g2(d,e)  
> puts “g1: #{a}, #{b}, #{c}”

Oooops, typo. That should of course read:

puts “g2: #{a}, #{b}, #{c}”

---

<div class="post-metadata">

**Author:** ![ronaldfischer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/67e7ee/32.png) [@ronaldfischer](https://www.ruby-forum.com/u/ronaldfischer)\
**Post date:** [August 31, 2007, 10:48am UTC](https://www.ruby-forum.com/t/dispatching-when-function-name-is-stated-as-a-symbol/113460/4 "2007-08-31T10:48:54Z")

</div>

> x=cb.call  
> name = x[0]  
> args = x[1…-1]  
> send(name, \*args);  
> end

Thank you! Works like a charm!

Ronald

---

<div class="post-metadata">

**Author:** ![ronaldfischer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/67e7ee/32.png) [@ronaldfischer](https://www.ruby-forum.com/u/ronaldfischer)\
**Post date:** [August 31, 2007, 4:01pm UTC](https://www.ruby-forum.com/t/dispatching-when-function-name-is-stated-as-a-symbol/113460/5 "2007-08-31T16:01:55Z")

</div>

On Aug 31, 2007, at 4:48 AM, Ronald F. wrote:

> > x=cb.call  
> > Ronald F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> > Phone: +49-89-452133-162

Why bother to split the name out of the array? Just do:

send(\*x)

If you really wanted to separate the name from the rest of the args,  
it might be more efficient (guessing, not benchmarked!) to say:

name = x.shift  
send(name, \*x)

-Rob

Rob B. [http://agileconsultingllc.com](http://agileconsultingllc.com)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![ronaldfischer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/67e7ee/32.png) [@ronaldfischer](https://www.ruby-forum.com/u/ronaldfischer)\
**Post date:** [August 31, 2007, 7:41pm UTC](https://www.ruby-forum.com/t/dispatching-when-function-name-is-stated-as-a-symbol/113460/6 "2007-08-31T19:41:22Z")

</div>

On Aug 31, 2007, at 4:48 AM, Ronald F. wrote:

> > x=cb.call  
> > name = x[0]  
> > args = x[1…-1]  
> > send(name, \*args);  
> > end

It can made even simpler:

def f(&cb)  
send(\*cb.call)  
end

def g1(a,b,c)  
puts “g1: #{a}, #{b}, #{c}”  
end

def g2(d,e)  
puts “g2: #{d}, #{e}”  
end

f { [:g1, 1, 2, 3] } # \>\> g1: 1, 2, 3  
f { [:g2, 2, 3] } # \>\> g2: 2, 3

Regards, Morton

---

<div class="post-metadata">

**Author:** ![ronaldfischer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/67e7ee/32.png) [@ronaldfischer](https://www.ruby-forum.com/u/ronaldfischer)\
**Post date:** [September 3, 2007, 9:34am UTC](https://www.ruby-forum.com/t/dispatching-when-function-name-is-stated-as-a-symbol/113460/7 "2007-09-03T09:34:46Z")

</div>

> send(\*x)

Simply because in my application, (1) the name gets prepended  
a prefix before sending it, and (2) a few other arguments  
are also put in the parameter list before sending. I didn’t  
mention these details, because I thought at the time of writing  
that they would only overly complicate the description of my  
case.

> If you really wanted to separate the name from the rest of the args,  
> it might be more efficient (guessing, not benchmarked!) to say:
> 
> name = x.shift  
> send(name, \*x)

Thank you for this suggestion.

Ronald
