Dispatching when function name is stated as a symbol

R

Ronald Fischer

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, ...,=20
which basically looks like this:

module M
def f(&cb)
...
x=3Dcb.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=20
is supposed to return an array, where the first element is a symbol
corresponding to one of the function names g1, g2 ...., and the=20
remaining array elements corresponding to the parameters of this
function. Hence, if=20
x=3Dcb.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 =3D> proc {|a,b,c] g1(a,b,c)}, :g2 =3D> 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
--=20
Ronald Fischer <[email protected]>
Phone: +49-89-452133-162

--=20
Ronald Fischer <[email protected]>
Phone: +49-89-452133-162
 
J

Jesús Gabriel y Galán

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.

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.
 
J

Jesús Gabriel y Galán

On 8/31/07, Ronald Fischer <[email protected]> wrote:
Would this work for you?

def f(&cb)
x=3Dcb.call
name =3D x[0]
args =3D 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}"

Oooops, typo. That should of course read:

puts "g2: #{a}, #{b}, #{c}"
end

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

Hope this helps,

Jesus.
 
R

Ronald Fischer

Hence, if
x=3Dcb.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.
=20
Would this work for you?
=20
def f(&cb)
x=3Dcb.call
name =3D x[0]
args =3D x[1..-1]
send(name, *args);
end

Thank you! Works like a charm!

Ronald

--=20
Ronald Fischer <[email protected]>
Phone: +49-89-452133-162
 
R

Rob Biedenharn

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

Thank you! Works like a charm!

Ronald

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 Biedenharn http://agileconsultingllc.com
(e-mail address removed)
 
M

Morton Goldberg

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

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
 
R

Ronald Fischer

Would this work for you?
def f(&cb)
x=3Dcb.call
name =3D x[0]
args =3D x[1..-1]
send(name, *args);
end
=20
Why bother to split the name out of the array? Just do:
=20
send(*x)

Simply because in my application, (1) the name gets prepended=20
a prefix before sending it, and (2) a few other arguments
are also put in the parameter list before sending. I didn't=20
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, =20
it might be more efficient (guessing, not benchmarked!) to say:
=20
name =3D x.shift
send(name, *x)

Thank you for this suggestion.

Ronald
--=20
Ronald Fischer <[email protected]>
Phone: +49-89-452133-162
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top