Ein Freund hat mich letzte Woche gefragt, wie man alle Variablen in einem Programm / einer Funktion / etc. Auflistet oder auflistet. zum Zwecke des Debuggens (im Wesentlichen um eine Momentaufnahme von allem zu erhalten, damit Sie sehen können, auf welche Variablen gesetzt ist oder ob sie überhaupt gesetzt sind). Ich habe mich ein bisschen umgesehen und einen relativ guten Weg für Python gefunden:
#! / usr / bin / python foo1 = "Hallo Welt" foo2 = "bar" foo3 = {"1": "a", "2": "b"} foo4 = "1 + 1" für den Namen in dir (): myvalue = eval (Name) Druckname, "ist", Typ (Name), "und ist gleich", myvalue
welches etwas ausgibt wie:
__builtins__ ist <type 'str'> und entspricht <module '__builtin__' (integriert)> __doc__ ist <Typ 'str'> und ist gleich None __file__ ist <type 'str'> und entspricht ./foo.py __name__ ist <type 'str'> und entspricht __main__ foo1 ist <type 'str'> und entspricht Hello world foo2 ist <type 'str'> und entspricht bar foo3 ist <Typ 'str'> und ist gleich {'1': 'a', '2': 'b'} foo4 ist <Typ 'str'> und ist gleich 1 + 1
Ich habe bisher einen Teilweg in PHP gefunden (mit freundlicher Genehmigung von Linktext ), aber es werden nur alle Variablen und ihre Typen aufgelistet, nicht der Inhalt:
<? php // ein paar Variablen erstellen $ bar = 'foo'; $ foo = 'bar'; // Erstelle ein neues Array Objekt $ arrayObj = neues ArrayObject (get_defined_vars ()); // Schleife über das Array-Objekt und Echo-Variablen und -Werte für ($ iterator = $ arrayObj-> getIterator (); $ iterator-> valid (); $ iterator-> next ()) { echo $ iterator-> key (). '=>'. $ iterator-> current (). '<br />'; }} ?>
Also sage ich es Ihnen: Wie listen Sie alle Variablen und ihren Inhalt in Ihrer Lieblingssprache auf?
Edit von VonC : Ich schlage vor, diese Frage folgt dem Geist einer kleinen " Code-Herausforderung ".
Wenn Sie nicht einverstanden sind, bearbeiten und entfernen Sie einfach das Tag und den Link.
Antworten:
Verwenden Sie in Python Locals, die ein Wörterbuch zurückgeben, das alle lokalen Bindungen enthält, und vermeiden Sie so die Auswertung:
quelle
So würde es in Ruby aussehen :
welches ausgegeben wird
Wollten Sie jedoch nicht den Objekttyp ausgeben, auf den die Variablen verweisen, anstatt den Typ, der zur Darstellung der Variablenkennung verwendet wird? IOW, die Art von
foo3
sollteHash
(oderdict
) statt seinString
, oder? In diesem Fall wäre der Codeund das Ergebnis ist
quelle
instance_variable_get(instance_variables[0])
IPython:
Sie können Spyder auch Ihrem Freund empfehlen , der diese Variablen ähnlich wie Matlab anzeigt und eine grafische Benutzeroberfläche für das zeilenweise Debuggen bietet.
quelle
In PHP könnten Sie dies tun:
quelle
In Lua ist die grundlegende Datenstruktur die Tabelle und sogar die globale Umgebung _G ist eine Tabelle. Eine einfache Aufzählung reicht also aus.
quelle
Bash:
Haftungsausschluss: Nicht meine Lieblingssprache!
quelle
env
, um herauszufinden, welche Werte nicht exportiert wurden.Ein vollständig rekursiver PHP-Einzeiler:
quelle
Erstens würde ich einfach einen Debugger verwenden ;-p Visual Studio verfügt beispielsweise über die Fenster "Locals" und "Watch", in denen alle gewünschten Variablen usw. angezeigt werden und die auf jede Ebene vollständig erweiterbar sind.
In C # kann man nicht sehr einfach auf Methodenvariablen zugreifen (und viele davon können vom Compiler entfernt werden) - aber Sie können über Reflektion auf Felder usw. zugreifen:
quelle
Perl. Behandelt keine
my
Einheimischen und filtert keine nutzlosen Referenzen heraus, aber alles im Paketumfang ist sichtbar.quelle
Matlab:
quelle
In der R-Sprache
und um alle Objekte aus dem Arbeitsspeicher zu entfernen
quelle
In Java wäre das Problem ähnlich wie in C #, nur in einem ausführlicheren Modus (ich weiß, ich weiß ;) Java ist ausführlich ... das haben Sie bereits klargestellt;) )
Sie können über Refection auf Objektfelder zugreifen, aber möglicherweise nicht einfach auf lokale Methodenvariablen. Das Folgende gilt also nicht für statischen Analysecode, sondern nur für das Laufzeit-Debugging.
quelle
AccessController
einer eigenständigen Anwendung nicht erforderlich (naja, essetAccessible
ist ohnehin nicht erforderlich, auf Ihre eigenen Felder zuzugreifen) oder dieif
Anweisung, zwischen zwei Fällen zu unterscheiden, die behandelt werden können Genauso wie beim Entfernen des veraltetentoString()
Aufrufs: FunktioniertSystem.out.println(aField.getName() + ": " + res);
, unabhängig davon, ob dies der Fallres
istnull
oder nicht. Und es ist auch nicht nötig, den Code auf mehrere Methoden zu verteilen ...In REBOL, leben alle Variablen in einem Kontext von Art
object!
. Es gibt einen globalen Kontext und jede Funktion hat ihren eigenen impliziten lokalen Kontext. Sie können explizit neue Kontexte erstellen, indem Sie einen neuen erstellenobject!
(oder diecontext
Funktion verwenden). Dies unterscheidet sich von herkömmlichen Sprachen, da Variablen (in REBOL "Wörter" genannt) einen Verweis auf ihren Kontext mit sich führen, selbst wenn sie den "Bereich" verlassen haben, in dem sie definiert wurden.Unter dem Strich können wir also in einem bestimmten Kontext die darin definierten Variablen auflisten. Wir werden die
context-words?
Funktion von Ladislav Mecir verwenden.Jetzt können wir alle im globalen Kontext definierten Wörter auflisten. (Es gibt viele von ihnen.)
Wir können auch eine Funktion schreiben, die dann die von ihr definierten Variablen auflistet.
Was wir in REBOL meines Wissens nicht tun können , ist den Kontextbaum hochzugehen, obwohl der Interpreter dies anscheinend perfekt kann, wenn er entscheidet, wie Wörter an ihre Kontexte gebunden werden. Ich denke, das liegt daran, dass der Kontextbaum (dh der Bereich) zum Zeitpunkt der Wortbindung eine "Form" haben kann, zum Zeitpunkt der Auswertung jedoch eine ganz andere.
quelle
Schnelle und schmutzige JavaScript-Lösung, wenn Sie FireBug installiert haben (oder einen anderen Browser mit console.log). Wenn Sie dies nicht tun, müssen Sie console.log in document.write ändern und am Ende Ihres als Inline-Skript ausführen. Ändern Sie MAX_DEPTH auf die gewünschte Rekursionsstufe (Vorsicht!).
quelle
Common Lisp:
So zeigen Sie auch alle gebundenen Werte an:
Dies ist eine lange Liste und nicht besonders nützlich. Ich würde wirklich den integrierten Debugger verwenden.
quelle
Hier ist eine Idee für oo-Sprachen.
Zuerst benötigen Sie so etwas wie toString () in Java, um aussagekräftige Inhalte zu drucken. Zweitens müssen Sie sich auf eine Objekthierarchie beschränken. Im Konstruktor des Root-Objekts (wie Any in Eiffel) registrieren Sie die Instanz beim Erstellen in einer Art globaler Liste. Während der Zerstörung melden Sie sich ab (stellen Sie sicher, dass Sie eine Datenstruktur verwenden, die ein schnelles Einfügen / Suchen / Entfernen ermöglicht). Während der Programmausführung können Sie jederzeit durch diese Datenstruktur gehen und alle dort registrierten Objekte drucken.
Aufgrund seiner Struktur könnte Eiffel für diesen Zweck sehr gut geeignet sein. Andere Sprachen haben Probleme mit Objekten, die nicht benutzerdefiniert sind (z. B. die JDK-Klassen). In Java ist es möglicherweise möglich, eine eigene Objektklasse mit einem Open-Source-JDK zu erstellen.
quelle