Znajomy zapytał mnie w zeszłym tygodniu, jak wyliczyć lub wyświetlić wszystkie zmienne w programie / funkcji / itp. do celów debugowania (zasadniczo uzyskania migawki wszystkiego, abyś mógł zobaczyć, jakie zmienne są ustawione lub czy w ogóle są ustawione). Rozejrzałem się trochę i znalazłem stosunkowo dobry sposób na Pythona:
#! / usr / bin / python foo1 = "Witaj świecie" foo2 = "bar" foo3 = {"1": "a", "2": "b"} foo4 = „1 + 1” dla nazwy w dir (): myvalue = eval (nazwa) wypisz nazwę, „jest”, wpisz (nazwa), „i jest równe”, moja wartość
który wyświetli coś takiego:
__builtins__ jest <typ 'str'> i jest równe <moduł '__builtin__' (wbudowany)> __doc__ to <type 'str'> i jest równe None __file__ to <typ „str”> i jest równe ./foo.py __name__ to <type 'str'> i jest równe __main__ foo1 to <type 'str'> i jest równe Hello world foo2 jest <typ 'str'> i jest równe bar foo3 jest <type 'str'> i jest równe {'1': 'a', '2': 'b'} foo4 jest <typ 'str'> i jest równe 1 + 1
Do tej pory znalazłem częściowy sposób w PHP (dzięki uprzejmości tekstu linku ), ale zawiera on tylko wszystkie zmienne i ich typy, a nie zawartość:
<? php // utwórz kilka zmiennych $ bar = 'foo'; $ foo = 'bar'; // utwórz nowy obiekt tablicy $ arrayObj = new ArrayObject (get_defined_vars ()); // pętla po obiekcie tablicy i echo zmiennych i wartości for ($ iterator = $ arrayObj-> getIterator (); $ iterator-> valid (); $ iterator-> next ()) { echo $ iterator-> key (). '=>'. $ iterator-> current (). '<br />'; } ?>
Powiedziałem ci więc: jak wypisujesz wszystkie zmienne i ich zawartość w swoim ulubionym języku?
Edit by VonC : Proponuję, aby to pytanie było zgodne z duchem małego „ wyzwania kodu ”.
Jeśli nie wyrażasz zgody, po prostu edytuj i usuń tag oraz link.
Odpowiedzi:
W Pythonie, używając lokalnych, które zwracają słownik zawierający wszystkie lokalne powiązania, unikając w ten sposób eval:
źródło
Tak by to wyglądało w Rubim :
które wyjdą
Jednak czy nie chodziło Ci o wyprowadzenie typu obiektu, do którego odwołuje się zmienna, zamiast typu używanego do reprezentowania identyfikatora zmiennej? IOW, typ
foo3
powinien byćHash
(lubdict
) zamiastString
, prawda? W takim przypadku kod byłbya wynik jest
źródło
instance_variable_get(instance_variables[0])
IPython:
Możesz również polecić Spyder swojemu przyjacielowi, który pokazuje te zmienne prawie tak, jak robi to Matlab i zapewnia GUI do debugowania linia po linii.
źródło
W php możesz to zrobić:
źródło
W Lua podstawową strukturą danych jest tabela, a nawet globalne środowisko _G jest tabelą. Tak więc proste wyliczenie załatwi sprawę.
źródło
Grzmotnąć:
Zastrzeżenie: To nie jest mój ulubiony język!
źródło
env
aby znaleźć wartości, które nie zostały wyeksportowane.W pełni rekursywny, jednowierszowy PHP:
źródło
Po pierwsze, użyłbym po prostu debugera ;-p Visual Studio, na przykład, ma okna „Lokalne” i „Obserwuj”, które pokażą wszystkie potrzebne zmienne itp., W pełni rozszerzalne do dowolnego poziomu.
W C # nie można bardzo łatwo dostać się do zmiennych metod (i wiele z nich może zostać usuniętych przez kompilator) - ale można uzyskać dostęp do pól itp. Poprzez odbicie:
źródło
Perl. Nie obsługuje
my
lokalnych i nie odfiltrowuje niektórych bezużytecznych odniesień, ale można zobaczyć wszystko w zakresie pakietu.źródło
Matlab:
źródło
W języku R.
i usunąć wszystkie obiekty z pamięci roboczej
źródło
W javie problem byłby podobny do C #, tylko w bardziej szczegółowym trybie (wiem, WIEM ;) Java jest gadatliwa ... już to wyjaśniłeś;) )
Możesz uzyskać dostęp do pól obiektu poprzez Refection, ale możesz nie mieć łatwego dostępu do metod zmiennych lokalnych. Dlatego poniższe informacje nie dotyczą kodu analizy statycznej, ale tylko debugowania w czasie wykonywania.
źródło
AccessController
jest zbędne w samodzielnej aplikacji (no cóż, i taksetAccessible
jest zbędne, aby mieć dostęp do własnych pól) lubif
stwierdzenie rozróżnienia między dwoma przypadkami, które można załatwić tak samo jak przy usuwaniu przestarzałegotoString()
wywołania:System.out.println(aField.getName() + ": " + res);
działa niezależnie od tego, czyres
jest,null
czy nie. Nie ma też potrzeby dzielenia kodu na wiele metod…W REBOL wszystkie zmienne znajdują się w kontekście typu
object!
. Istnieje kontekst globalny, a każda funkcja ma swój własny domyślny kontekst lokalny. Możesz jawnie tworzyć nowe konteksty, tworząc nowyobject!
(lub używająccontext
funkcji). Różni się to od tradycyjnych języków, ponieważ zmienne (zwane w języku REBOL „słowami”) niosą ze sobą odniesienie do otaczającego ich kontekstu, nawet jeśli opuściły „zakres”, w którym zostały zdefiniowane.Zatem najważniejsze jest to, że biorąc pod uwagę kontekst, możemy wyświetlić listę zmiennych, które definiuje. Skorzystamy z
context-words?
funkcji Ladislava Mecira .Teraz możemy wymienić wszystkie słowa zdefiniowane w kontekście globalnym. (Jest ich dużo .)
Możemy również napisać funkcję, która następnie wyświetli listę zmiennych, które definiuje.
To, czego nie możemy zrobić w REBOL-u, o ile wiem, to chodzić po drzewie kontekstu, chociaż tłumacz wydaje się być w stanie zrobić to doskonale, kiedy decyduje, jak powiązać słowa z ich kontekstami. Myślę, że dzieje się tak dlatego, że drzewo kontekstu (tj. Zasięg) może mieć jeden „kształt” w momencie wiązania słowa, a zupełnie inny w momencie oceny.
źródło
Szybkie i brudne rozwiązanie JavaScript, jeśli masz zainstalowany FireBug (lub inną przeglądarkę z console.log). Jeśli tego nie zrobisz, będziesz musiał zmienić console.log na document.write i uruchomić go jako wbudowany skrypt na końcu twojego. Zmień MAX_DEPTH na ile chcesz poziomów rekurencji (uważaj!).
źródło
Wspólny Lisp:
Aby również pokazać wszystkie wartości powiązane:
To jest długa lista i niezbyt przydatna. Naprawdę użyłbym zintegrowanego debuggera.
źródło
Oto pomysł na języki oo.
Najpierw potrzebujesz czegoś takiego jak toString () w Javie, aby wydrukować znaczącą zawartość. Po drugie - musisz ograniczyć się do jednej hierarchii obiektów. W konstruktorze obiektu głównego (jak Any w Eiffel) rejestrujesz instancję podczas tworzenia na jakiejś globalnej liście. Podczas niszczenia wyrejestrowujesz się (pamiętaj, aby użyć jakiejś struktury danych, która umożliwia szybkie wstawianie / wyszukiwanie / usuwanie). W dowolnym momencie podczas wykonywania programu możesz przejść przez tę strukturę danych i wydrukować wszystkie zarejestrowane tam obiekty.
Ze względu na swoją konstrukcję, Eiffel może być bardzo dobry do tego celu. Inne języki mają problemy z obiektami, które nie są zdefiniowane przez użytkownika (np. Klasy jdk). W Javie może być możliwe stworzenie własnej klasy obiektów przy użyciu jdk typu open source.
źródło