关于元编程:使用Ruby中的方法名称从字符串调用方法

Calling a Method From a String With the Method's Name in Ruby

我怎么能做到他们在这里说的,但在鲁比呢?

你将如何在一个对象上执行这个函数?你将如何做一个全局函数(见上文Jetxee的回答)?

示例代码:

1
2
3
4
5
6
7
8
9
10
11
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()

更新:你如何获得全局方法?还是我的全球职能?

我试过这条附加线路

1
puts methods

加载和行在未列出的位置更改。


直接在对象上调用函数

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

按预期返回3

或模块功能

1
2
3
FileUtils.send('pwd')
# or
FileUtils.public_send(:pwd)

以及局部定义的方法

1
2
3
4
5
6
7
def load()
    puts"load() function was executed."
end

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

文档:

  • 江户十一〔一〕号
  • 埃多克斯1〔2〕


使用此:

1
2
3
4
> a ="my_string"
> meth = a.method("size")
> meth.call() # call the size method
=> 9

简单,对吗?

至于全局,我认为Ruby方法应该是使用methods方法搜索它。


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

典型调用(供参考):

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

使用send

1
s.send(:length) #=> 6

。使用call

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

。使用eval

1
eval"s.length" #=> 6

nbsp;

基准

1
2
3
4
5
6
7
8
9
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" } }
}

...as you can see, instantiating a method object is the fastest dynamic way in calling a method, also notice how slow using eval is.

1
2
3
4
5
6
7
8
9
10
11
12
13
#######################################
#####   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)

值得一提的是,这篇博文对这三种方法进行了更多的阐述,并展示了如何检查这些方法是否存在。


我个人会设置一个哈希函数引用,然后使用字符串作为哈希的索引。然后用它的参数调用函数引用。这样做的好处是不允许错误的字符串调用您不想调用的内容。另一种方法基本上是使用eval字符串。不要这样做。

别偷懒,把你的问题全部打出来,而不是链接到某个东西上。