Comment faire pour exécuter la CISR.démarrer dans le contexte de l'actuelle classe
J'ai été tout simplement en passant par PragProg des Essais en Continu Avec Ruby, où ils parlent de l'invocation IRB
dans le contexte de la classe en cours d'inspecter le code manuellement.
Cependant, ils citent que si vous appelez IRB.start
dans une classe, auto est prédéfini, et fait référence à l'objet que nous étions lorsque le départ a été appelé qui n'est pas vrai dans mon cas.
Même pour exemple très simple comme
a = "hello"
require 'irb'
ARGV.clear # otherwise all script parameters get passed to IRB
IRB.start
Lorsque j'essaie d'accéder à la a
variable, j'ai l'évidente
NameError: undefined local variable or method `a' for main:Object
Il ne fonctionne que quand je change de a
à la variable globale
$a = "hello"
require 'irb'
ARGV.clear # otherwise all script parameters get passed to IRB
IRB.start
alors je peux y accéder
irb(main):001:0> $a
=> 1
Est-il un moyen de contourner cela pour l'accès local et les variables d'instance de la classe en cours?
Vous devez vous connecter pour publier un commentaire.
Je vous suggère d'essayer ce en ripl, un cisr alternative. L'exemple ci-dessus fonctionne:
Noter que les variables locales de travailler en raison de votre passage de l'actuelle liaison avec l' :l'option de reliure.
Vous pourriez peut-être faire la même chose dans la cisr, mais comme il est mal documenté et non-testés, vos chances de le faire proprement sont minces à aucun.
Comme vous l'avez déjà découvert,
self
ne fait pas référence à l'objet où la CISR a été commencé, mais à laTOPLEVEL_BINDING
, ce qui semble être une instance de laObject
classe elle-même.Vous pouvez toujours exécuter un CISR séance avec une classe spécifique ou un objet comme le contexte, mais ce n'est pas aussi simple que juste de départ de la CISR.
Si vous vous souciez de démarrage de la CISR avec un contexte spécifique, alors il est vraiment facile à faire quand vous êtes à partir de la CISR manuellement. Juste au début de la CISR normalement, puis d'appeler la
irb
méthode, en lui passant l'objet/classe que vous voulez, selon le contexte.Vous pouvez également démarrer une session de la CISR par programme et spécifier le contexte, mais il n'est pas aussi facile qu'il devrait être parce que vous avez de reproduire une partie de la CISR la start-up de code. Après beaucoup d'expérimentation et de creuser autour de la CISR, le code source, j'ai été en mesure de venir avec quelque chose qui fonctionne:
Au lieu de mondial vous pouvez utiliser les variables d'instance, par exemple:
IRB.start
(c'est à dire, en remplacement de@a
dans ce code aveca
ne fonctionnerait pas), mais à la différence des variables globales ils ne polluent pas l'espace de noms global (juste celui de l'objet principal). Dans tous les cas, d'autres réponses déjà mention des façons d'obtenir des locaux de travail, ainsi, si à l'aide d'une bibliothèque ou d'un peu plus de travail n'est pas un problème, puis ceux-ci sont de meilleures alternatives. (Je préfère Soulever moi-même.)Utilisation Pry:
/usr/local/share/gems/gems/term-ansicolor-1.2.2/lib/term/ansicolor.rb:188:in 'color': wrong number of arguments (0 for 1..2) (ArgumentError) from /usr/local/share/gems/gems/pry-0.10.0/lib/pry/output.rb:35:in 'decolorize_maybe'
Voici comment appeler de la CISR à partir de votre script dans le contexte de l'endroit où vous l'appel de la CISR.commencer..
De l'exécution de votre script va invoquer la CISR. Lorsque vous arrivez à la demande que vous avez une chose à faire...
Profitez-en!
Comme des Rubis 2.4.0, vous pouvez le faire:
Cela va démarrer une IBR REPL où vous aurez la valeur correcte pour
self
et vous pourrez accéder à toutes les variables locales et les variables d'instance qui sont dans la portée. Tapez Ctrl+D ouquit
pour reprendre le cours de votre Ruby programme.Ma solution pour Ruby 2.2.3. Il est très similaire à Bryant
Je peux accéder à des variables locales et des variables d'instance. Le
require 'irb'
de cours pourrait être en haut du fichier. Le réglage debanana
et@banana
est juste pour prouver que je peux y accéder à partir de la cisr invite. Le to_s est une méthode qui permet d'obtenir une assez prompte, mais il ya d'autres choix. Et il n'y a pas vraiment de raison de faire une méthode distincte, mais comme il est, vous pouvez plop ce dans n'importe où et cela devrait fonctionner.La ruby-debug-base gem ajoute un binding_n méthode à la Noyau module et cela vous donnera accès à la liaison de l'objet qui peut être utilisé dans un eval pour donner accès à la pile des appels de variables. N'oubliez pas de problème Débogueur.début pour activer la pile des appels de suivi.
Voici un exemple montrant son utilisation pour connaître ce qui se passe à l'intérieur de de la cisr (un Rubis programme). On pourrait se poser la besoin's et Débogueur.début à l'intérieur de votre propre code Ruby ainsi.
Si vous êtes prêt à exécuter une version patchée de Rubis pour 1.9.2 voir http://gitnub.com/rocky/rb-threadframe pour ce que je pense est le meilleur accès à la pile d'appel. Rubinius fournit cette fonctionnalité intégrée dans la via Rubinius::VM.backtrace.