[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

calling random

Boris Schmid

2/8/2009 4:15:00 PM

Apologies, I have been out of using ruby for a while, and ran into
trouble when I tried to do the below. What is the normal way to call
apply a list of arguments to a list of functions?

def f1(n)
puts "f1: #{n}"
end

def f2(n)
puts "f2: #{n}"
end

irb(main):008:0> [f1,f2].each {|fun| [1,2,3,4].each {|val| fun(val)}}
--
Posted via http://www.ruby-....

10 Answers

Boris Schmid

2/8/2009 4:16:00 PM

0

Sorry for the mismatched title, a more appropriate one would be: "how to
combine a list of functions with a list of arguments?"
--
Posted via http://www.ruby-....

Alex Fenton

2/8/2009 4:28:00 PM

0

Boris Schmid wrote:
> Apologies, I have been out of using ruby for a while, and ran into
> trouble when I tried to do the below. What is the normal way to call
> apply a list of arguments to a list of functions?
>
> def f1(n)
> puts "f1: #{n}"
> end
>
> def f2(n)
> puts "f2: #{n}"
> end

[:f1, :f2].each do | fun |
[1, 2, 3, 4].each { | x | Object.send(fun, x) }
end

Ruby doesn't have functions, just methods. What look like functions
above (a def outside a class body) creates methods in the Object class.

"send" is the generic way to call any object's method using a name. It
accepts a string or symbol (hence :f1 above) followed by the arguments.

a

David A. Black

2/8/2009 4:38:00 PM

0

Hi --

On Mon, 9 Feb 2009, Boris Schmid wrote:

> Apologies, I have been out of using ruby for a while, and ran into
> trouble when I tried to do the below. What is the normal way to call
> apply a list of arguments to a list of functions?
>
> def f1(n)
> puts "f1: #{n}"
> end
>
> def f2(n)
> puts "f2: #{n}"
> end
>
> irb(main):008:0> [f1,f2].each {|fun| [1,2,3,4].each {|val| fun(val)}}

If f1 and f2 contain actual method objects, you can use call:

f1,f2 = method(:f1), method(:f2)
[f1,f2].each {|m| [1,2,3,4].each {|e| m.call(e) } }

Mixing f(unction) and m(ethod) terminology a bit... but that's OK,
because it will also work if f1 and f2 are Proc objects (which are
basically anonymous functions.

If you have strings or symbols, you can use them to get the method
objects (see above), or you can use send:

["f1", "f2"].each {|m| [1,2,3,4].each {|e| send(m,e)} }


David

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.r...
Coming in 2009: The Well-Grounded Rubyist (http://manning....)

http://www.wis... => Independent, social wishlist management!

Boris Schmid

2/8/2009 6:58:00 PM

0

Am I correct if I remember that using send is quite expensive in
cpu-time? Especially when I am using it millions of times.. $pop is
about 5000 hosts large.

10000.times {
# Events to happen to every host this 0.1 year:
["birth","death","infect","evolve"].shuffle.each {|event|

next if event == "birth" and EVENTS_BIRTH > rand
next if event == "death" and EVENTS_DEATH > rand
next if event == "infect" and EVENTS_INFECTION > rand
next if event == "evolve" and EVENTS_EVOLUTION > rand
$pop.each {|host|
next if host == nil
send(event,host)
}
}
}

What I could do is make birth,death,infect and evolve methods of the
host class, and perhaps use call then. Does that make sense?


David A. Black wrote:
> Hi --
>
> On Mon, 9 Feb 2009, Boris Schmid wrote:
>
>> end
>>
>> irb(main):008:0> [f1,f2].each {|fun| [1,2,3,4].each {|val| fun(val)}}
>
> If f1 and f2 contain actual method objects, you can use call:
>
> f1,f2 = method(:f1), method(:f2)
> [f1,f2].each {|m| [1,2,3,4].each {|e| m.call(e) } }
>
> Mixing f(unction) and m(ethod) terminology a bit... but that's OK,
> because it will also work if f1 and f2 are Proc objects (which are
> basically anonymous functions.
>
> If you have strings or symbols, you can use them to get the method
> objects (see above), or you can use send:
>
> ["f1", "f2"].each {|m| [1,2,3,4].each {|e| send(m,e)} }
>
>
> David
>
> --
> David A. Black / Ruby Power and Light, LLC
> Ruby/Rails consulting & training: http://www.r...
> Coming in 2009: The Well-Grounded Rubyist (http://manning....)
>
> http://www.wis... => Independent, social wishlist management!

--
Posted via http://www.ruby-....

Boris Schmid

2/8/2009 8:56:00 PM

0

Boris Schmid wrote:
> Am I correct if I remember that using send is quite expensive in
> cpu-time? Especially when I am using it millions of times.. $pop is
> about 5000 hosts large.
>

Ah. It's not that bad. send("fib",2) is about twice as slow as fib(2).
So I lose 2 minutes in 2 hours of simulation, which is fine.

Thanks for the answers!
--
Posted via http://www.ruby-....

Alex Fenton

2/8/2009 10:08:00 PM

0

Boris Schmid wrote:
> Am I correct if I remember that using send is quite expensive in
> cpu-time? Especially when I am using it millions of times.. $pop is
> about 5000 hosts large.
>
> 10000.times {
> # Events to happen to every host this 0.1 year:
> ["birth","death","infect","evolve"].shuffle.each {|event|

Using #send with a String argument is slower than using it with a
Symbol. Benchmark:

-------
require 'benchmark'
class Foo
def bar; end
end

a_foo = Foo.new

TIMES = 1_000_000

puts "Direct", Benchmark::measure { TIMES.times { a_foo.bar } }
puts "Symbol", Benchmark::measure { TIMES.times { a_foo.send(:bar) }
puts "String", Benchmark::measure { TIMES.times { a_foo.send("bar") } }
-------

With Ruby 1.8:

Direct
0.290000 0.000000 0.290000 ( 0.294786)
Symbol
0.380000 0.000000 0.380000 ( 0.385319)
String
0.550000 0.000000 0.550000 ( 0.556780)

With Ruby 1.9, the difference between #send(a_symbol) and calling the
method directly is negligible:

Direct
0.210000 0.000000 0.210000 ( 0.209512)
Symbol
0.210000 0.000000 0.210000 ( 0.210357)
String
0.490000 0.000000 0.490000 ( 0.500568)

alex

David A. Black

2/8/2009 10:16:00 PM

0

Hi --

On Mon, 9 Feb 2009, Alex Fenton wrote:

> Boris Schmid wrote:
>> Am I correct if I remember that using send is quite expensive in cpu-time?
>> Especially when I am using it millions of times.. $pop is about 5000 hosts
>> large.
>>
>> 10000.times {
>> # Events to happen to every host this 0.1 year:
>> ["birth","death","infect","evolve"].shuffle.each {|event|
>
> Using #send with a String argument is slower than using it with a Symbol.
> Benchmark:
>
> -------
> require 'benchmark'
> class Foo
> def bar; end
> end
>
> a_foo = Foo.new
>
> TIMES = 1_000_000
>
> puts "Direct", Benchmark::measure { TIMES.times { a_foo.bar } }
> puts "Symbol", Benchmark::measure { TIMES.times { a_foo.send(:bar) }
> puts "String", Benchmark::measure { TIMES.times { a_foo.send("bar") } }
> -------
>
> With Ruby 1.8:
>
> Direct
> 0.290000 0.000000 0.290000 ( 0.294786)
> Symbol
> 0.380000 0.000000 0.380000 ( 0.385319)
> String
> 0.550000 0.000000 0.550000 ( 0.556780)
>
> With Ruby 1.9, the difference between #send(a_symbol) and calling the method
> directly is negligible:
>
> Direct
> 0.210000 0.000000 0.210000 ( 0.209512)
> Symbol
> 0.210000 0.000000 0.210000 ( 0.210357)
> String
> 0.490000 0.000000 0.490000 ( 0.500568)

However, calling #intern/to_sym is (slightly) slower than just sending
a string. This is Ruby 1.9.1:

Direct
0.150000 0.000000 0.150000 ( 0.157290)
Symbol
0.170000 0.000000 0.170000 ( 0.166353)
String
0.470000 0.000000 0.470000 ( 0.476854)
#intern
0.520000 0.020000 0.540000 ( 0.537574)

So if you've got a string already, it's probably not worth doing the
conversion explicitly.


David

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.r...
Coming in 2009: The Well-Grounded Rubyist (http://manning....)

http://www.wis... => Independent, social wishlist management!

Julian Leviston

2/9/2009 4:25:00 AM

0

Huh?

Blog: http://random8.ze...
Learn rails: http://sensei.ze...

On 09/02/2009, at 3:16 AM, Boris Schmid <borisschmid@gmail.com> wrote:

> Sorry for the mismatched title, a more appropriate one would be:
> "how to
> combine a list of functions with a list of arguments?"
> --
> Posted via http://www.ruby-....
>

Ken Bloom

2/9/2009 5:05:00 AM

0

On Sun, 08 Feb 2009 15:56:04 -0500, Boris Schmid wrote:

> Boris Schmid wrote:
>> Am I correct if I remember that using send is quite expensive in
>> cpu-time? Especially when I am using it millions of times.. $pop is
>> about 5000 hosts large.
>>
>>
> Ah. It's not that bad. send("fib",2) is about twice as slow as fib(2).
> So I lose 2 minutes in 2 hours of simulation, which is fine.
>
> Thanks for the answers!

It should be a bit faster if you use :fib instead of "fib", because the
ruby runtime has to internally "fib" to :fib every time you call send().

--Ken

--
Chanoch (Ken) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu...

Dylan Evans

2/9/2009 7:59:00 AM

0

[Note: parts of this message were removed to make it a legal post.]

On Mon, Feb 9, 2009 at 2:16 AM, Boris Schmid <borisschmid@gmail.com> wrote:

> Sorry for the mismatched title, a more appropriate one would be: "how to
> combine a list of functions with a list of arguments?"
> --
> Posted via http://www.ruby-....
>
> I'm taking a stab in the dark here but are you trying to pass more than one
procedures as arguments to a function?
if so, then try:
def foo(x, y)
x.call
y.call
end

foo proc { puts 'x' }, proc { puts 'y' }

Anyway i could spend hours trying to understand that question.
--
The UNIX system has a command, nice ... in order to be nice to the other
users. Nobody ever uses it." - Andrew S. Tanenbaum