web-dev-qa-db-fra.com

Appel d'une méthode à partir d'une chaîne portant le nom de la méthode dans Ruby

Comment puis-je faire ce dont ils parlent ici , mais en Ruby?

Comment feriez-vous la fonction sur un objet? et comment feriez-vous une fonction globale (voir jetxee's réponse sur le post mentionné)?

EXEMPLE DE CODE:

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: Comment accéder aux méthodes globales? ou mes fonctions globales?

J'ai essayé cette ligne supplémentaire

puts methods

et load et row_change n'étaient pas listés.

148
BuddyJoe

Pour appeler des fonctions directement sur un objet

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

qui retourne 3 comme prévu

ou pour une fonction de module

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

et une méthode définie localement

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

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

Documentation:

216
Colin Gravill

Utilisez ceci:

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

Simple, non?

En ce qui concerne global, je pense que la méthode Ruby consisterait à effectuer une recherche à l'aide de la méthode methods.

33
Geo

Trois façons: send/call/eval - et leurs points de repère

Invocation typique (pour référence):

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

Utiliser send

s.send(:length) #=> 6

Utiliser call

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

Utiliser eval

eval "s.length" #=> 6

Des repères

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" } } 
} 

... comme vous pouvez le constater, l'instanciation d'un objet de méthode est le moyen dynamique le plus rapide pour appeler une méthode. Notez également la lenteur avec 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)

Le mérite en revient à ceci article de blog qui explique un peu plus les trois méthodes et montre également comment vérifier si les méthodes existent.

32
cwd

Personnellement, je configurerais un hachage pour utiliser des références, puis utiliserais la chaîne comme index du hachage. Vous appelez ensuite la référence de fonction avec ses paramètres. Cela a l’avantage de ne pas autoriser la mauvaise chaîne à appeler quelque chose que vous ne voulez pas appeler. L’autre méthode consiste à utiliser essentiellement eval la chaîne. Ne faites pas cela.

PS ne soyez pas paresseux et tapez votre question au lieu de la relier à quelque chose.

3
dlamblin