[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Dispatching when function name is stated as a symbol

Ronald Fischer

8/31/2007 8:18:00 AM

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 Fischer <ronald.fischer@venyon.com>
Phone: +49-89-452133-162

--
Ronald Fischer <ronald.fischer@venyon.com>
Phone: +49-89-452133-162

6 Answers

Jesús Gabriel y Galán

8/31/2007 8:35:00 AM

0

On 8/31/07, Ronald Fischer <ronald.fischer@venyon.com> wrote:
> 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.

Jesús Gabriel y Galán

8/31/2007 8:39:00 AM

0

On 8/31/07, Jesús Gabriel y Galán <jgabrielygalan@gmail.com> wrote:
> On 8/31/07, Ronald Fischer <ronald.fischer@venyon.com> wrote:

> 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}"

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
> => nil
> irb(main):018:0> f {[:g2, 1, 2, 3]}
> g2: 1, 2, 3
> => nil
>
> Hope this helps,
>
> Jesus.
>

Ronald Fischer

8/31/2007 8:48:00 AM

0

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

--
Ronald Fischer <ronald.fischer@venyon.com>
Phone: +49-89-452133-162

Rob Biedenharn

8/31/2007 2:01:00 PM

0

On Aug 31, 2007, at 4:48 AM, Ronald Fischer wrote:
>>> 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
>
> --
> Ronald Fischer <ronald.fischer@venyon.com>
> 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 Biedenharn http://agileconsult...
Rob@AgileConsultingLLC.com




Morton Goldberg

8/31/2007 5:40:00 PM

0

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

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

Ronald Fischer

9/3/2007 7:34:00 AM

0

> >> Would this work for you?
> >>
> >> def f(&cb)
> >> x=cb.call
> >> name = x[0]
> >> args = x[1..-1]
> >> send(name, *args);
> >> end
>
> Why bother to split the name out of the array? Just do:
>
> 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
--
Ronald Fischer <ronald.fischer@venyon.com>
Phone: +49-89-452133-162