Вызов метода из строки с именем метода в Ruby - PullRequest
145 голосов
/ 11 сентября 2009

Как я могу сделать то, о чем они говорят здесь , но в 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()

UPDATE: Как вы попадаете на глобальные методы? или мои глобальные функции?

Я пробовал эту дополнительную строку

puts methods

и load and row_change, где нет в списке.

Ответы [ 4 ]

212 голосов
/ 11 сентября 2009

Для вызова функций непосредственно на объекте

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

Документация:

33 голосов
/ 11 сентября 2009

Используйте это:

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

Простой, верно?

Что касается global , я думаю, что Ruby мог бы найти его, используя метод methods.

32 голосов
/ 08 августа 2015

Три способа: 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

Тесты * * 1023 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 голосов
/ 11 сентября 2009

Лично я бы настроил хеш для ссылок на функции, а затем использовал бы строку как индекс для хеша. Затем вы вызываете ссылку на функцию с ее параметрами. Это имеет то преимущество, что не позволяет неправильной строке вызывать то, что вы не хотите вызывать. Другой способ - в основном eval строка. Не делай этого.

PS Не ленитесь и напишите весь вопрос, вместо того, чтобы ссылаться на что-то.

...