[आपकी पसंदीदा भाषा यहां] [बंद] के एक कार्यक्रम में सभी चरों की गणना या सूची बनाना


80

एक मित्र ने पिछले हफ्ते मुझसे पूछा कि किसी प्रोग्राम / फंक्शन / वगैरह के सभी वेरिएबल्स की गणना या सूची कैसे बनाई जाए। डिबगिंग के उद्देश्यों के लिए (अनिवार्य रूप से सब कुछ का एक स्नैपशॉट प्राप्त करना ताकि आप देख सकें कि चर क्या सेट हैं, या यदि वे सभी पर सेट हैं)। मैंने चारों ओर देखा और पायथन के लिए अपेक्षाकृत अच्छा तरीका पाया:

#! / usr / बिन / अजगर                                                                                                                                                                                                                           
foo1 = "नमस्ते दुनिया"
foo2 = "बार"
foo3 = {"1": "ए",
        "2": "बी"}
foo4 = "1 + 1"

dir में नाम के लिए ():
    myvalue = eval (नाम)
    प्रिंट नाम, "है", प्रकार (नाम), "और बराबर है", myvalue

जो कुछ इस तरह का उत्पादन करेगा:

__builtins__ <प्रकार 'str'> है और <मॉड्यूल '__builtin__' (अंतर्निहित)> के बराबर है
__doc__ <प्रकार 'str'> है और कोई भी नहीं के बराबर है
__file__ <प्रकार 'str'> है और ./foo.py के बराबर है
__name__ <प्रकार 'str'> है और __main__ के बराबर है
foo1 <टाइप 'str'> है और हैलो वर्ल्ड के बराबर है
foo2 <प्रकार 'str'> है और बार के बराबर है
foo3 <टाइप 'str'> है और {'1': 'a', '2': 'b'} के बराबर है
foo4 <प्रकार 'str'> है और 1 + 1 के बराबर है

मैंने अब तक PHP में एक आंशिक तरीका पाया है ( लिंक टेक्स्ट के सौजन्य से ) लेकिन यह केवल सभी चर और उनके प्रकारों को सूचीबद्ध करता है, सामग्री को नहीं:

<? php
// कुछ वैरिएबल बनाएं
$ बार = 'फू';
$ फू = 'बार';
// एक नई सरणी ऑब्जेक्ट बनाएँ
$ arrayObj = new ArrayObject (get_defined_vars ());
// सरणी ऑब्जेक्ट पर लूप और चर और मूल्यों को प्रतिध्वनित करें
के लिए ($ पुनरावृत्ति = $ arrayObj-> getIterator (); $ iterator-> मान्य) (; $ iterator-> अगला ()
        {
        इको $ इटरेटर-> की ()। '=>'। $ पुनरावृत्ति-> वर्तमान ()। '<br />';
        }
?>

इसलिए मैंने इसे आपके सामने रखा: आप अपनी पसंदीदा भाषा में सभी चर और उनकी सामग्री को कैसे सूचीबद्ध करते हैं?


VonC द्वारा संपादित करें : मैं प्रस्तावित करता हूं कि यह प्रश्न थोड़ा " कोड-चैलेंज " की भावना का अनुसरण करता है ।
यदि आप सहमत नहीं हैं, तो बस टैग और लिंक को संपादित करें और निकालें।


4
अजगर में मैं सिर्फ आपके द्वारा दिखाए गए dir / eval के बजाय लोकल / ग्लोबल्स का उपयोग करूँगा। निचे देखो।
हारून मेनापा

PHP में यह बहुत आसान हो सकता है, मेरा उत्तर देखें।
पीम जगर

1
मैं असहमत हूं, मेरी योजना समग्र रूप से सबसे सुंदर समाधान का चयन करना है और उत्तर और प्रार्थना के रूप में सेट करना है। मुझे लगता है कि अगर मैं इनमें से प्रत्येक के लिए एक व्यक्तिगत प्रश्न पूछूं, जो "उचित" प्रश्न के रूप में अधिक योग्य होगा, लेकिन यह ध्यान देने योग्य है कि विभिन्न भाषाओं में उपयोग की जाने वाली विधियां अक्सर अन्य भाषाओं के साथ ओवरलैप होती हैं (यानी डिबगर / आदि का उपयोग करें)।
कर्ट

1
महान पद। मुझे चर की एक सूची प्राप्त करने के लिए इसकी आवश्यकता थी जिसे मैंने एक मॉड्यूल में परिभाषित किया था। 'not name.startswith (' __ ')' (अजगर का उपयोग करके) के एक अतिरिक्त परीक्षण के साथ यह मेरे लिए चमत्कार करता है। बहुत बहुत धन्यवाद
ShadowFlame

2
आह। बहुत व्यापक होने के लिए दोनों को 1) बंद नहीं होना चाहिए क्योंकि यह कई भाषाओं का है और 2) एक ही भाषा के प्रश्नों के लिए "डुप्लिकेट रीडायरेक्ट" है।
चार्ल्स मेरियम

जवाबों:


93

अजगर में, स्थानीय लोगों का उपयोग करते हुए, जो सभी स्थानीय बाइंडिंग वाले शब्दकोश देता है, इस प्रकार, बचने से बचता है:

>>> 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'>}

11

यह वही है जो रूबी में दिखाई देगा :

#!/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 स्ट्रिंग है और "हैलो वर्ल्ड" के बराबर है
foo2 स्ट्रिंग है और "बार" के बराबर है
foo3 स्ट्रिंग है और {"1" => "a", "2" => "b"} के बराबर है
foo4 स्ट्रिंग है और "1 + 1" के बराबर है

हालाँकि, चर पहचानकर्ता का प्रतिनिधित्व करने के लिए इस्तेमाल किए गए प्रकार के बजाय चर संदर्भ के प्रकार का उत्पादन करने का क्या मतलब नहीं था? IOW, सही के बजाय , (या ) का प्रकार foo3होना चाहिए ? उस स्थिति में, कोड होगाHashdictString

#!/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 स्ट्रिंग है और "हैलो वर्ल्ड" के बराबर है
foo2 स्ट्रिंग है और "बार" के बराबर है
foo3 हैश है और {"1" => "a", "2" => "b"} के बराबर है
foo4 स्ट्रिंग है और "1 + 1" के बराबर है

1
आपको संभवतः यह भी शामिल करना चाहिए: example_variables Global_variables class_variables constants
राडो

कम से कम रूबी 2.2 में मुझे इसका उपयोग करना थाinstance_variable_get(instance_variables[0])
21-1238 पर jberryman

10

IPython:

whos

आप अपने दोस्त को स्पाइडर की सिफारिश कर सकते हैं जो उन चरों को दिखाता है जैसे मतलाब करता है और लाइन-बाय-लाइन डिबगिंग के लिए GUI प्रदान करता है।


9

Php में आप ऐसा कर सकते हैं:

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

3
+1 नाइस, यह फ़ंक्शन अस्पष्ट है लेकिन यह यहां के सबसे छोटे उदाहरणों में से एक है, और कुछ अभी भी PHP बेकार कहते हैं। =)
एलिक्स एक्सल

9

लुआ में मूलभूत डेटा संरचना तालिका है और यहां तक ​​कि वैश्विक वातावरण _G एक तालिका है। तो, एक सरल गणना चाल करेगी।

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



4

सबसे पहले, मैं बस एक डिबगर का उपयोग करूंगा; -प विज़ुअल स्टूडियो, उदाहरण के लिए, "लोकल" और "वॉच" विंडो है जो सभी चर आदि दिखाएगा जो आप चाहते हैं, किसी भी स्तर पर पूरी तरह से विस्तार योग्य।

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

पर्ल। 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";
}



2

जावा में, समस्या सी # के समान होगी, केवल एक अधिक क्रिया मोड में (मुझे पता है, मुझे पता है ;) जावा क्रिया है ... आपने पहले ही स्पष्ट कर दिया है; )

आप रीफ़ेक्शन के माध्यम से ऑब्जेक्ट फ़ील्ड तक पहुँच सकते हैं, लेकिन आप स्थानीय चर को विधि के लिए आसानी से एक्सेस नहीं कर सकते हैं। तो निम्नलिखित स्थैतिक विश्लेषण कोड के लिए नहीं है, बल्कि केवल रनवे डीबगिंग के लिए है।

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");
            }
        }
    }
}

या आप Apache Commons Beanutils का उपयोग कर सकते हैं।
एरोन दिगुल्ला

यह जावा नहीं है जो क्रिया है, लेकिन आपका कोड है। अर्थहीन टिप्पणियां, इसके साथ शुरू करने के लिए, साथ ही पूरी तरह से अप्रचलित संचालन, जैसे कि पूरी तरह से निपटने के AccessControllerलिए एक अकेले खड़े आवेदन setAccessibleमें अनावश्यक है (ठीक है, वैसे भी अपने स्वयं के क्षेत्रों तक पहुंचने के लिए अनावश्यक है) या ifदो मामलों के बीच अंतर करने के लिए बयान जिसे संभाला जा सकता है। अप्रचलित toString()कॉल को हटाते समय उसी तरह से : System.out.println(aField.getName() + ": " + res);काम करता है, भले ही resवह हो nullया न हो। और कोड को कई तरीकों पर फैलाने की आवश्यकता नहीं है, या तो ...
होल्गर

1

REBOL में, सभी चर प्रकार के संदर्भ में रहते हैं object!। एक वैश्विक संदर्भ है, और प्रत्येक फ़ंक्शन का अपना निहित स्थानीय संदर्भ है। आप एक नया object!(या उपयोग करके) स्पष्ट रूप से नए संदर्भ बना सकते हैंcontext फ़ंक्शन ) । यह पारंपरिक भाषाओं से अलग है क्योंकि चर (जिन्हें आरईबीओएल में "शब्द" कहा जाता है) अपने संदर्भ के संदर्भ को अपने साथ ले जाते हैं, तब भी जब उन्होंने "गुंजाइश" छोड़ दी है जिसमें वे परिभाषित किए गए थे।

तो, लब्बोलुआब यह है कि, एक संदर्भ दिया जाता है, हम इसे परिभाषित करने वाले चर को सूचीबद्ध कर सकते हैं। हम लदिस्लाव मेकिर के context-words?फंक्शन का उपयोग करेंगे ।

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

अब हम वैश्विक संदर्भ में परिभाषित सभी शब्दों को सूचीबद्ध कर सकते हैं। (उनमें से एक बहुत हैं।)

probe context-words? system/words

हम एक फ़ंक्शन भी लिख सकते हैं जो तब परिभाषित चर को सूचीबद्ध करता है।

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

REBOL में हम क्या नहीं कर सकते हैं , जहां तक ​​मुझे पता है, संदर्भ पेड़ पर चलना है, हालांकि दुभाषिया यह पूरी तरह से अच्छी तरह से करने में सक्षम प्रतीत होता है जब यह फैसला करता है कि शब्दों को उनके संदर्भों में कैसे बांधें। मुझे लगता है कि इसका कारण यह है कि संदर्भ पेड़ (यानी, गुंजाइश) का एक शब्द होने के समय एक "आकार" हो सकता है, लेकिन उस मूल्यांकन के समय यह काफी अन्य होता है।


1

यदि आपके पास FireBug स्थापित है (या कंसोल.लॉग के साथ एक और ब्राउज़र) तो त्वरित और गंदा जावास्क्रिप्ट समाधान। यदि आप नहीं करते हैं, तो आपको अपने दस्तावेज़ के अंत में कंसोल.log को दस्तावेज़ में लिखना होगा, और इनलाइन स्क्रिप्ट के रूप में चलना होगा। 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);
    }
})();

0

आम लिस्प:

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

सभी बाध्य मान दिखाने के लिए:

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

यह एक लंबी सूची है, और विशेष रूप से उपयोगी नहीं है। मैं वास्तव में एकीकृत डिबगर का उपयोग करूंगा।


0

यहाँ ओओ-भाषाओं के लिए एक विचार है।

सबसे पहले आपको सार्थक सामग्री को प्रिंट करने के लिए जावा में कुछ (जैसे) स्ट्रिंग की आवश्यकता होती है। दूसरा - आपको अपने आप को एक वस्तु-पदानुक्रम तक सीमित करना होगा। रूट-ऑब्जेक्ट (जैसे कि एफिल में कोई भी) के निर्माता में, किसी प्रकार की वैश्विक सूची में निर्माण पर आपके उदाहरण को पंजीकृत करता है। विनाश के दौरान, आप डेरेगिस्टर (कुछ डेटा संरचना का उपयोग करना सुनिश्चित करें जो तेजी से सम्मिलित / खोज / हटाने की अनुमति देता है)। कार्यक्रम के निष्पादन के दौरान किसी भी समय, आप इस डेटा-संरचना के माध्यम से चल सकते हैं और वहां पंजीकृत सभी वस्तुओं को प्रिंट कर सकते हैं।

इसकी संरचना के कारण, इस उद्देश्य के लिए एफिल बहुत अच्छा हो सकता है। अन्य भाषाओं में उन वस्तुओं के साथ समस्या है जो उपयोगकर्ता-परिभाषित नहीं हैं (उदाहरण के लिए jdk-classes)। जावा में कुछ ओपन-सोर्स jdk का उपयोग करके अपना ऑब्जेक्ट-क्लास बनाना संभव हो सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.