使用Ruby中的方法名称从字符串调用方法

Bud*_*Joe 151 ruby metaprogramming

我怎么能在这里做他们正在谈论的事情,但是在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()
Run Code Online (Sandbox Code Playgroud)

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

我试过这个额外的一行

puts methods
Run Code Online (Sandbox Code Playgroud)

和load和row_change未列出的地方.

Col*_*ill 222

直接在对象上调用函数

a = [2, 2, 3]
a.send("length")
# or
a.public_send("length")
Run Code Online (Sandbox Code Playgroud)

按预期返回3

或模块功能

FileUtils.send('pwd')
# or
FileUtils.public_send(:pwd)
Run Code Online (Sandbox Code Playgroud)

和一个本地定义的方法

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

send('load')
# or
public_send('load')
Run Code Online (Sandbox Code Playgroud)

文档:

  • 很高兴你在源头寻找东西!:) (11认同)
  • +1这有效.这可能是一个愚蠢的跟进......但是为什么我在Ruby源代码中找不到发送单词 - C:\ ruby​​\lib\ruby​​\1.8\fileutils.rb?以为我会在那里找到发送功能. (3认同)

Geo*_*Geo 33

用这个:

> a = "my_string"
> meth = a.method("size")
> meth.call() # call the size method
=> 9
Run Code Online (Sandbox Code Playgroud)

简单吧?

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


cwd*_*cwd 33

三种方式:send/ call/ eval- 和他们的基准

典型调用(供参考):

s= "hi man"
s.length #=> 6
Run Code Online (Sandbox Code Playgroud)

运用 send

s.send(:length) #=> 6
Run Code Online (Sandbox Code Playgroud)

运用 call

method_object = s.method(:length) 
p method_object.call #=> 6
Run Code Online (Sandbox Code Playgroud)

运用 eval

eval "s.length" #=> 6
Run Code Online (Sandbox Code Playgroud)

 

基准

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" } } 
} 
Run Code Online (Sandbox Code Playgroud)

...正如您所看到的,实例化方法对象是调用方法的最快动态方式,同时注意使用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)
Run Code Online (Sandbox Code Playgroud)

感谢这篇博文,其中详细阐述了这三种方法,并展示了如何检查方法是否存在.

  • 如果你想通过 send 调用发送一些参数,请使用类似 ClassName.send("method_name", arg1, arg2) 的内容 (2认同)