web-dev-qa-db-ja.com

[ここでお気に入りの言語]のプログラム内のすべての変数を列挙またはリストします

友人から先週、プログラム/関数/など内のすべての変数を列挙または一覧表示する方法を尋ねられました。デバッグの目的で(基本的にすべてのスナップショットを取得して、設定されている変数を確認できるようにするか、設定されているかどうかを確認します)。私は少し調べて、Pythonの比較的良い方法を見つけました。

#!/ usr/bin/python 
 foo1 = "Hello world" 
 foo2 = "bar" 
 foo3 = {"1": "a"、 
 "2": "b"} 
 foo4 = "1 + 1" 
 
 dir():
 myvalue = evalの名前(name)
 print name、 "is"、type(name)、 "and is equal to"、myvalue 

次のようなものが出力されます:

 __ builtins__は<type 'str'>で、<module '__builtin__'(ビルトイン)> 
 __ doc__は<type 'str'>でNone 
 __ file__は<type 'str'>で、。/ foo.py 
 __ is <type 'str'>と等しく、__ main __ 
 foo1は<type 'str'>と等しくHello world 
 foo2は<type 'str'>に等しく、bar 
 foo3は<type 'str'>に等しく、{'1': 'a'、 '2に等しい':' b '} 
 foo4は<type' str '>であり、1 + 1 
と等しい

私はこれまでのところPHP( link text のおかげ))で部分的な方法を見つけましたが、それはすべての変数とそのタイプのみをリストし、内容はリストしません:

 <?php 
 //いくつかの変数を作成します
 $ bar = 'foo'; 
 $ foo = 'bar'; 
 //新しい配列オブジェクトを作成する
 $ arrayObj = new ArrayObject(get_defined_vars()); 
 //配列オブジェクトをループし、変数と値をエコーし​​ます
 for($ iterator = $ arrayObj -> getIterator(); $ iterator-> valid(); $ iterator-> next())
 {
 echo $ iterator-> key()。 '=>'。 $ iterator-> current()。 '<br />'; 
} 
?> 

だから私はあなたにそれを置きます:どのようにあなたの好きな言語ですべての変数とその内容をリストしますか?


VonC による編集:この質問は、ちょっとした " code-challenge "の精神に従ってください。
同意しない場合は、タグとリンクを編集して削除してください。

77
Kurt

Pythonでは、すべてのローカルバインディングを含む辞書を返すlocalsを使用して、evalを回避します。

>>> foo1 = "Hello world"
>>> foo2 = "bar"
>>> foo3 = {"1":"a",
...         "2":"b"}
>>> foo4 = "1+1"

>>> import pprint
>>> pprint.pprint(locals())
{'__builtins__': <module '__builtin__' (built-in)>,
 '__doc__': None,
 '__name__': '__main__',
 'foo1': 'Hello world',
 'foo2': 'bar',
 'foo3': {'1': 'a', '2': 'b'},
 'foo4': '1+1',
 'pprint': <module 'pprint' from '/usr/lib/python2.5/pprint.pyc'>}
89
Aaron Maenpaa

これは Ruby でどのように見えるかです:

#!/usr/bin/env Ruby

foo1 = 'Hello world'
foo2 = 'bar'
foo3 = { '1' => 'a', '2' => 'b' }
foo4 = '1+1'

b = binding
local_variables.each do |var|
  puts "#{var} is #{var.class} and is equal to #{b.local_variable_get(var).inspect}"
end

出力する

foo1は文字列であり、「Hello world」と等しい
 foo2は文字列であり、「bar」と等しい
 foo3は文字列であり、{"1" => "a"、 "2と等しい"=>" b "} 
 foo4は文字列で、「1 + 1」に等しい

ただし、変数識別子を表すために使用される型ではなく、変数が参照するオブジェクトの型を出力するつもりはありませんでしたか? IOW、foo3のタイプはHashではなくdict(またはString)でなければなりませんか?その場合、コードは次のようになります

#!/usr/bin/env Ruby

foo1 = 'Hello world'
foo2 = 'bar'
foo3 = { '1' => 'a', '2' => 'b' }
foo4 = '1+1'

b = binding
local_variables.each do |var|
  val = b.local_variable_get(var)
  puts "#{var} is #{val.class} and is equal to #{val.inspect}"
end

結果は

foo1は文字列であり、「Hello world」に等しい
 foo2は文字列であり、「bar」に等しい
 foo3はハッシュであり、{"1" => "a"、 "2に等しい"=>" b "} 
 foo4は文字列で、「1 + 1」に等しい
11
Jörg W Mittag

PHPでこれを行うことができます:

$defined = get_defined_vars(); 
foreach($defined as $varName => $varValue){
 echo "$varName is of type ".gettype($varValue)." and has value $varValue <br>";
}
9
Pim Jager

Luaでは、基本的なデータ構造はtableであり、グローバル環境_Gもテーブルです。そのため、単純な列挙がトリックを行います。

for k,v in pairs(_G) do
  print(k..' is '..type(v)..' and is equal to '..tostring(v))
end
9

IPython:

whos

Matlabのように変数を表示し、行ごとのデバッグ用のGUIを提供する Spyder を友人に推奨することもできます。

8
Eder Santana

バッシュ:

set

免責事項:私の好きな言語ではありません!

6
too much php

完全に再帰的なPHPワンライナー:

print_r(get_defined_vars());
6
LapTop006

Matlab:

who
4
Dario

まず、単にデバッガーを使用します。たとえば、-p Visual Studioには、「Locals」ウィンドウと「Watch」ウィンドウがあり、必要なすべての変数などを表示し、任意のレベルに完全に拡張できます。

C#では、メソッド変数を実際に取得することは非常に簡単ではありません(そして、それらの多くはコンパイラによって削除されます)。しかし、リフレクションを介してフィールドなどにアクセスできます。

static class Program { // formatted for minimal vertical space
    static object foo1 = "Hello world", foo2 = "bar",
                  foo3 = new[] { 1, 2, 3 }, foo4;
    static void Main() {
        foreach (var field in typeof(Program).GetFields(
                BindingFlags.Static | BindingFlags.NonPublic)) {
            var val = field.GetValue(null);
            if (val == null) {
                Console.WriteLine("{0} is null", field.Name);
            } else {
                Console.WriteLine("{0} ({1}) = {2}",
                    field.Name, val.GetType().Name, val);
            }
        }
    }
}
4
Marc Gravell

Perl。 myローカルを処理せず、いくつかの役に立たない参照を除外しませんが、パッケージスコープ内のすべてを見ることができます。

my %env = %{__PACKAGE__ . '::'};
while (($a, $b) = each %env) {
    print "\$$a = $$b\n";
    print "\@$a = (@$b)\n";
    print "%$a = (@{[%$b]})\n";
    print "*$a = $b\n";
}
3
ephemient

Javaでは、問題はC#に似ていますが、より冗長なモードでのみです(I KNOW;) Javaは冗長です... すでにそれを明確にしました;)

Refectionを使用してオブジェクトフィールドにアクセスできますが、メソッドローカル変数に簡単にアクセスできない場合があります。したがって、以下は静的解析コード用ではなく、実行時デバッグ専用です。

package test;

import Java.lang.reflect.Field;
import Java.security.AccessController;
import Java.security.PrivilegedAction;

/**
 * 
 * @author <a href="https://stackoverflow.com/users/6309/vonc">VonC</a>
 */
public class DisplayVars
{

    private static int field1 = 1;
    private static String field2 = "~2~";
    private boolean isField = false;

    /**
     * @param args
     */
    public static void main(final String[] args)
    {
        final Field[] someFields = DisplayVars.class.getDeclaredFields();
        try
        {
            displayFields(someFields);
        } catch (IllegalAccessException e)
        {
            e.printStackTrace();
        }
    }

    /**
     * @param someFields
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     */
    @SuppressWarnings("unchecked")
    public static void displayFields(final Field[] someFields)
            throws IllegalAccessException
    {
        DisplayVars anObject = new DisplayVars();
        Object res = null;
        for (int ifields = 0; ifields < someFields.length; ifields++)
        {
            final Field aField = someFields[ifields];
            AccessController.doPrivileged(new PrivilegedAction() {
                public Object run()
                {
                    aField.setAccessible(true);
                    return null; // nothing to return
                }
            });
            res = aField.get(anObject);
            if (res != null)
            {
                System.out.println(aField.getName() + ": " + res.toString());
            } else
            {
                System.out.println(aField.getName() + ": null");
            }
        }
    }
}
2
VonC

R言語で

ls()

そして、作業メモリからすべてのオブジェクトを削除します

rm(list=ls(all=TRUE))
2
Tiago Zortea

FireBug(またはconsole.logのある別のブラウザー)がインストールされている場合の迅速で汚れたJavaScriptソリューション。そうしない場合は、console.logをdocument.writeに変更し、の最後にインラインスクリプトとしてatを実行する必要があります。 MAX_DEPTHを必要な再帰レベル数に変更します(注意してください!)。

(function() {
    var MAX_DEPTH = 0;
    function printObj(name, o, depth) {
        console.log(name + " type: '"+typeof o+"' value: " + o);

        if(typeof o == "function" || depth >= MAX_DEPTH) return;
        for(var c in o) {
            printObj(name+"."+c, o[c], depth+1);
        }
    }
    for(var o in window) {
        printObj(o, window[o], 0);
    }
})();
1
gregers

REBOLでは、すべての変数はタイプobject!context内に存在します。グローバルコンテキストがあり、すべての関数には独自の暗黙的なローカルコンテキストがあります。新しいobject!を作成する(またはcontext関数を使用する)ことにより、明示的に新しいコンテキストを作成できます。これは、変数(REBOLでは「単語」と呼ばれます)は、定義された「スコープ」を離れた場合でも、それらのコンテキストへの参照を保持するため、従来の言語とは異なります。

つまり、一番下の行は、コンテキストが与えられると、それが定義する変数をリストできるということです。 Ladislav Mecirの context-words? 関数を使用します。

context-words?: func [ ctx [object!] ] [ bind first ctx ctx ]

これで、グローバルコンテキストで定義されたすべての単語をリストできます。 (lotがあります。)

probe context-words? system/words

また、定義する変数をリストする関数を作成することもできます。

enumerable: func [a b c /local x y z] [
  probe context-words? bind? 'a
]

私が知っている限りでは、REBOLでできないことができないのは、コンテキストツリーをたどることですコンテキストに単語をバインドする方法を決定するときに完全にうまくいきます。これは、コンテキストツリー(つまりスコープ)が、Wordがバインドされた時点で1つの「形状」を持ち、評価された時点ではまったく別の形状を持つためだと思います。

1
Gregory Higley

これがoo言語のアイデアです。

最初に、JavaのようなtoString()のようなものが必要です。意味のあるコンテンツを印刷します。2番目-オブジェクト階層を1つに制限する必要があります。 )、ある種のグローバルリストでの作成時にインスタンスを登録します。破棄中に登録を解除します(高速な挿入/検索/削除を可能にするデータ構造を必ず使用してください)。プログラム実行中はいつでもこのデータを確認できます。 -そこに登録されているすべてのオブジェクトを構造化し、印刷します。

その構造のために、エッフェルはこの目的に非常に適しているかもしれません。他の言語には、ユーザー定義ではないオブジェクト(jdkクラスなど)に問題があります。 Javaでは、オープンソースjdkを使用して独自のオブジェクトクラスを作成できる場合があります。

0
Tobias Langner

共通のLISP:

(do-all-symbols (x) (print x))

すべてのバインドされた値も表示するには:

(do-all-symbols (x) (print x) (when (boundp x) (print (symbol-value x))))

これは長いリストであり、特に有用ではありません。私は本当に統合デバッガーを使用します。

0
Svante