Je sais que la méthode class indique quel est le nom de la classe d'un objet, comment pourrais-je connaître le nom de la méthode invoquante? Y a-t-il un moyen de le savoir?Existe-t-il un moyen de connaître la méthode d'invocation?
Répondre
Examining the Ruby Call Stack parts cette information:
Avez-vous déjà voulu regarder la pile d'appel sans soulever une exception pour le faire?
caller.each {|c| puts c}
appelant est une méthode Kernal qui vous permet de le faire, alors l'appelant [0] vous permettra de connaître l'appelant immédiat de la fonction.
un hack rapide pour obtenir que le nom de la fonction pourrait être
caller[0][/`\S+/].chop[1..-1]
ce renverront le nom de la méthode d'appel en tant que chaîne, que vous pouvez ensuite utiliser comme vous le voulez
Ruby l'implémentation de Kernel#caller
a été faite avec String
pour des raisons de performances et de collecte des ordures. Si vous voulez faire une analyse plus sophistiquée de la pile d'appels, jetez un oeil à ce blog:
http://eigenclass.org/hiki/ruby+backtrace+data
L'auteur passe par deux implémentations différentes d'une meilleure pile appel objet graphique, celui mis en oeuvre en Ruby pur avec le (pas très connu) Kernel#set_trace_func
méthode et un autre qui fonctionne comme une extension C à l'IRM.
Une application de production ne doit pas utiliser autre chose que l'implémentation Kernel#caller
fournie avec Ruby. Si vous utilisez largement les extensions ci-dessus, vous finirez probablement par tuer la capacité de Ruby à collecter efficacement les ordures et ralentir votre processus (j'estime) jusqu'à plusieurs ordres de grandeur.
Vous pouvez écrire quelque chose comme ceci:
module Kernel
private
def who_is_calling? # Or maybe def who_just_called?
caller[1] =~ /`([^']*)'/ and $1
end
end
Et puis vous avez ces petits tests:
irb(main):056:0* def this_is_a_method
irb(main):057:1> puts "I, 'this_is_a_method', was called upon by: '#{who_is_calling?}'"
irb(main):058:1> end
=> nil
irb(main):059:0> def this_is_a_method_that_calls_another
irb(main):060:1> this_is_a_method
irb(main):061:1> end
=> nil
irb(main):062:0> this_is_a_method_that_calls_another
I, 'this_is_a_method', was called upon by: 'this_is_a_method_that_calls_another'
=> nil
irb(main):063:0> this_is_a_method
I, 'this_is_a_method', was called upon by: 'irb_binding'
=> nil
irb(main):064:0>
Non pas que ce n'est pas une question valable et tout, mais avoir à regarder l'appel pile signifie généralement que vous faites quelque chose de mal. –