Pas un doublon de "Obtenir le nom de la méthode actuellement exécutée dans Ruby." Cette question demande le nom de la méthode appelante, pas le nom de la méthode actuelle.
Cela donne le nom de la méthode appelante, mais cela ne donne aucune indication à quel module ou classe appartient la méthode. Est-ce possible?
thomthom
@thomthom Oui, c'est possible, vous pouvez appeler self.class.name pour voir le nom de la classe
Thorin
Excellente utilisation de l'expression régulière comme index de chaîne! Peut également utilisercaller[0][/`(.*)'/,1]
aks
1
Cela ne semble pas fonctionner dans Rails 5.2.1. Dans le contrôleur Rails, cela revient "block in make_lambda". Je suppose que c'est pour Ruby uniquement.
Quel est l'avantage de cela par rapport à l'approche de DigitalRoss?
Andrew Grimm
2
Plus propre et plus précis. Plutôt que de faire la recherche, utilisez une méthode de tableau pour diviser les caractères indésirables en fonction de la position (ce qui pourrait être incorrect).
New Alexandria le
2
Pourquoi ne pas simplement utiliser l'appelant [0] [/ `(. *) '/, 1]? Je ne suis pas un gourou des expressions régulières, mais cela semble fonctionner.
collimarco
7
@collimarco Tant que la chaîne ne contient pas de chaîne 'au-delà de celle que vous recherchez (et je suppose que ce n'est pas le cas), le résultat sera le même, bien sûr. Cependant, [^']*cela fonctionnera mieux car le moteur d'expression régulière arrêtera d'essayer de faire correspondre cette partie à l'expression au moment où il atteint a '(votre version ira à la fin, puis reviendra parce qu'elle n'a pas trouvé de 'à la fin). La différence est assez négligeable dans ce cas bien sûr, mais c'est une bonne habitude à éviter .dans les regex si possible.
Au lieu de cela, vous pouvez l'écrire en tant que fonction de bibliothèque et faire un appel là où c'est nécessaire. Le code est le suivant:
moduleCallChaindefself.caller_method(depth=1)
parse_caller(caller(depth+1).first).last
end
private
# Copied from ActionMailerdefself.parse_caller(at)if/^(.+?):(\d+)(?::in`(.*)')?/ =~ at
file = Regexp.last_match[1]
line = Regexp.last_match[2].to_i
method = Regexp.last_match[3]
[file, line, method]
end
end
end
Pour déclencher la méthode de module ci-dessus, vous devez appeler comme ceci:
caller = CallChain.caller_method
Un lien vers une solution potentielle est toujours le bienvenu, mais veuillez ajouter du contexte autour du lien afin que vos collègues utilisateurs aient une idée de ce que c'est et pourquoi il est là. Citez toujours la partie la plus pertinente d'un lien important, au cas où le site cible serait inaccessible ou serait définitivement hors ligne. Tenez compte du fait qu'être à peine plus qu'un lien vers un site externe est une raison possible pour savoir pourquoi et comment certaines réponses sont-elles supprimées? .
Xavi López
@ XaviLópez a mis à jour la réponse, veuillez rectifier si je fais mal ou
quelque chose me
1
Merci d'avoir amélioré votre réponse. Malheureusement, je n'ai pas assez de connaissances sur Ruby pour pouvoir commenter correctement cet article, mais la réponse semble correcte maintenant. J'ai supprimé mon vote défavorable. Bonne chance :-)
Xavi López
2
Afin de voir les informations sur l'appelant et l'appelé dans n'importe quel langage, que ce soit ruby, java ou python, vous voudrez toujours regarder la trace de la pile. Dans certains langages, tels que Rust et C ++, il existe des options intégrées au compilateur pour activer une sorte de mécanisme de profilage que vous pouvez afficher pendant l'exécution. Je crois qu'il en existe un pour Ruby appelé ruby-prof.
Et comme mentionné ci-dessus, vous pouvez consulter la pile d'exécution pour ruby. Cette pile d'exécution est un tableau contenant des objets d'emplacement de trace arrière.
Tout ce que vous devez savoir sur cette commande est essentiellement le suivant:
Réponses:
ou peut-être...
la source
caller[0][/`(.*)'/,1]
"block in make_lambda"
. Je suppose que c'est pour Ruby uniquement.Dans Ruby 2.0.0, vous pouvez utiliser:
C'est beaucoup plus rapide que la solution Ruby 1.8+:
Sera inclus dans
backports
quand j'aurai le temps (ou une pull request!).la source
caller_locations[0].label
sur Ruby 2.2.0 sinon vous avez toujours lesend_action
résultatUtilisez
caller_locations(1,1)[0].label
(pour rubis> = 2.0)Edit : Ma réponse disait d'utiliser
__method__
mais j'avais tort, elle renvoie le nom de la méthode actuelle.la source
j'utilise
la source
'
au-delà de celle que vous recherchez (et je suppose que ce n'est pas le cas), le résultat sera le même, bien sûr. Cependant,[^']*
cela fonctionnera mieux car le moteur d'expression régulière arrêtera d'essayer de faire correspondre cette partie à l'expression au moment où il atteint a'
(votre version ira à la fin, puis reviendra parce qu'elle n'a pas trouvé de'
à la fin). La différence est assez négligeable dans ce cas bien sûr, mais c'est une bonne habitude à éviter.
dans les regex si possible.Que diriez-vous
Imo beaucoup plus propre.
la source
Au lieu de cela, vous pouvez l'écrire en tant que fonction de bibliothèque et faire un appel là où c'est nécessaire. Le code est le suivant:
Pour déclencher la méthode de module ci-dessus, vous devez appeler comme ceci:
caller = CallChain.caller_method
référence de code de
la source
Afin de voir les informations sur l'appelant et l'appelé dans n'importe quel langage, que ce soit ruby, java ou python, vous voudrez toujours regarder la trace de la pile. Dans certains langages, tels que Rust et C ++, il existe des options intégrées au compilateur pour activer une sorte de mécanisme de profilage que vous pouvez afficher pendant l'exécution. Je crois qu'il en existe un pour Ruby appelé ruby-prof.
Et comme mentionné ci-dessus, vous pouvez consulter la pile d'exécution pour ruby. Cette pile d'exécution est un tableau contenant des objets d'emplacement de trace arrière.
Tout ce que vous devez savoir sur cette commande est essentiellement le suivant:
appelant (début = 1, longueur = nil) → tableau ou nil
la source