Ruby中的动态方法调用 [英] Dynamic method calling in Ruby

查看:70
本文介绍了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.

所以我的问题是:是否有任何理由要使用.sendeval?为什么不总是使用最快的方法呢?这些调用动态方法的方法还有什么其他区别?

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?

call 需要一种方法对象, 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆