web-dev-qa-db-ja.com

Rubyにメソッド名を指定して文字列からメソッドを呼び出す

彼らが話していることをどうすれば ここ でできますか?

オブジェクトに対してどのように機能しますか?そして、どのようにグローバル機能を実行しますか(言及されている投稿のjetxeeの answer を参照)

例のコード:

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()

UPDATE:グローバルメソッドにどうやって行きますか?または私のグローバル機能?

私はこの追加のラインを試しました

puts methods

リストされていない場所でloadおよびrow_changeを実行します。

148
BuddyJoe

オブジェクトで関数を直接呼び出すには

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')

ドキュメンテーション:

216
Colin Gravill

これを使って:

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

シンプルでしょ?

globalに関しては、Rubyの方法はmethodsメソッドを使用して検索することだと思います。

33
Geo

3つの方法: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)

クレジットはこれになります ブログ投稿 3つのメソッドについてもう少し詳しく説明し、メソッドが存在するかどうかを確認する方法も示します。

32
cwd

個人的には、関数参照にハッシュを設定し、その文字列をハッシュのインデックスとして使用します。次に、パラメーターを使用して関数参照を呼び出します。これには、間違った文字列が呼び出したくないものを呼び出すことを許可しないという利点があります。他の方法は、基本的に eval 文字列です。こんなことしないで。

PSは何かにリンクするのではなく、怠け者ではなく、実際に質問全体を入力します。

3
dlamblin