Ruby中的动态方法调用 [英] Dynamic method calling in Ruby
问题描述
据我所知,有三种方法可以在Ruby中动态调用方法:
As far as I am aware there are three ways to dynamically call a method in Ruby:
方法1:
s = SomeObject.new
method = s.method(:dynamic_method)
method.call
方法2:
s = SomeObject.new
s.send(:dynamic_method)
方法3:
s = SomeObject.new
eval "s.dynamic_method"
通过对它们进行基准测试,我确定了方法1迄今为止最快,方法2较慢,方法3迄今为止最慢.
By benchmarking them I have established that Method 1 is by far the fastest, Method 2 is slower, and Method 3 is by far the slowest.
我还发现.call
和.send
都允许调用私有方法,而eval
不允许.
I have also found that .call
and .send
both allow calling private methods, while eval
does not.
所以我的问题是:是否有任何理由要使用.send
或eval
?为什么不总是使用最快的方法呢?这些调用动态方法的方法还有什么其他区别?
So my question is: is there any reason to ever use .send
or eval
? Why would you not always just use the fastest method? What other differences do these methods of calling dynamic methods have?
推荐答案
是否有任何理由要使用
send
?
class Foo
def method_missing(name)
"#{name} called"
end
end
Foo.new.send(:bar) #=> "bar called"
Foo.new.method(:bar).call #=> undefined method `bar' for class `Foo' (NameError)
是否有任何理由要使用
eval
?
eval
计算任意表达式,它是不只是用于调用方法.
eval
evaluates arbitrary expressions, it's not just for calling a method.
关于基准测试,send
似乎比method
+ call
快:
Regarding benchmarks, send
seems to be faster than method
+ call
:
require 'benchmark'
class Foo
def bar; end
end
Benchmark.bm(4) do |b|
b.report("send") { 1_000_000.times { Foo.new.send(:bar) } }
b.report("call") { 1_000_000.times { Foo.new.method(:bar).call } }
end
结果:
user system total real
send 0.210000 0.000000 0.210000 ( 0.215181)
call 0.740000 0.000000 0.740000 ( 0.739262)
这篇关于Ruby中的动态方法调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!