在 Ruby 中从具有方法名称的字符串调用方法

我怎样才能做他们正在谈论的 给你,但在 Ruby?

如何对一个对象执行这个函数?你将如何做一个全局函数(见文章中提到的 jetxee 的 回答) ?

示例代码:

event_name = "load"


def load()
puts "load() function was executed."
end


def row_changed()
puts "row_changed() function was executed."
end


#something here to see that event_name = "load" and run load()

更新: 你如何得到全局方法? 或者我的全局函数?

我试过这个额外的线路

puts methods

以及未列出的装载和 row _ change。

110592 次浏览

就个人而言,我将设置一个散列函数引用,然后使用字符串作为散列的索引。然后使用函数的参数调用函数引用。这样做的好处是不允许错误的字符串调用您不想调用的内容。另一种方法基本上是 eval字符串。别这么做。

不要偷懒,把你的问题全部打出来,而不是链接到什么东西上。

直接调用对象上的函数

a = [2, 2, 3]
a.send("length")
# or
a.public_send("length")

如预期返回3

或者模块功能

FileUtils.send('pwd')
# or
FileUtils.public_send(:pwd)

和一个局部定义的方法

def load()
puts "load() function was executed."
end


send('load')
# or
public_send('load')

文件:

用这个:

> a = "my_string"
> meth = a.method("size")
> meth.call() # call the size method
=> 9

很简单,对吧?

至于 全球性的,我认为 Ruby 的方法是使用 methods方法来搜索它。

三种方法: send/call/eval-及其基准

典型调用(参考) :

s= "hi man"
s.length #=> 6

使用 send

s.send(:length) #=> 6

使用 call

method_object = s.method(:length)
p method_object.call #=> 6

使用 eval

eval "s.length" #=> 6

基准

require "benchmark"
test = "hi man"
m = test.method(:length)
n = 100000
Benchmark.bmbm {|x|
x.report("call") { n.times { m.call } }
x.report("send") { n.times { test.send(:length) } }
x.report("eval") { n.times { eval "test.length" } }
}

正如你所看到的,实例化一个方法对象是调用一个方法的最快的动态方式,同时也要注意使用 eval 是多么的慢。

#######################################
#####   The results
#######################################
#Rehearsal ----------------------------------------
#call   0.050000   0.020000   0.070000 (  0.077915)
#send   0.080000   0.000000   0.080000 (  0.086071)
#eval   0.360000   0.040000   0.400000 (  0.405647)
#------------------------------- total: 0.550000sec


#          user     system      total        real
#call   0.050000   0.020000   0.070000 (  0.072041)
#send   0.070000   0.000000   0.070000 (  0.077674)
#eval   0.370000   0.020000   0.390000 (  0.399442)

值得称道的是这个 博客文章,它详细介绍了这三种方法,并且还展示了如何检查这些方法是否存在。