2010-09-04 14 views
6

जब आप डिबगिंग करते हैं, तो यह करने में बहुत उपयोगी होता है:मैं दो बार नाम टाइप किए बिना एक चर नाम और उसके मूल्य को कैसे मुद्रित कर सकता हूं?

var = calc() 
print("var:", var) 

क्या कोई ऐसी भाषा है जहां यह करना आसान है? सी और सी ++ में आप स्ट्रिंगिफ़ मैक्रो ऑपरेटर # का उपयोग कर सकते हैं और रूबी में मुझे यह प्रश्न मिला:

Ruby - print the variable name and then its value

समाधान जो प्रतीक का उपयोग करता है: var और a block मैं चाहता हूं।

डी में, मैंने इसका इस्तेमाल किया:

void trace(alias msg)() { 
    writeln(msg.stringof ~ ":" ~ to!string(msg)); 
} 

लेकिन मुझे यकीन नहीं है कि यह सबसे अच्छा तरीका है, क्योंकि यह केवल साधारण मामलों में काम करता है। मैंने कई तरीकों की कोशिश की है, लेकिन कभी-कभी आप स्ट्रिंग प्राप्त कर सकते हैं, लेकिन मान नहीं (क्योंकि वेरिएबल स्कोप से बाहर हैं), या आपको पहले टेम्पलेट को मिलाकर फ़ंक्शन को कॉल करना होगा।

और अन्य भाषाओं के बारे में क्या? अजगर? एफ #? बू? शैल स्क्रिप्ट (जो भी खोल)? पर्ल? (मैं पर्ल से दूर रहना पसंद करता हूं)। Tcl? लिस्प, योजना? जावा? (यह बेहद असंभव है कि जावा ऐसा कर सकता है)।

यहां तक ​​कि उन भाषाओं में जहां मुझे किसी प्रकार का समाधान मिला, यह केवल साधारण मामलों के लिए काम करता है। अगर मैं एक मनमाना अभिव्यक्ति मुद्रित करना चाहता हूं तो क्या होगा?

अगर मैं एक भाषा डिजाइन कर रहा था, तो यह सुविधा एक जरूरी होगी। :-)

उत्तर

5

यहाँ एक बहुत ही सामान्य है, लेकिन थोड़ा बदसूरत तरह से डी में यह करने के लिए, संकलन समय समारोह मूल्यांकन (CTFE) का उपयोग कर एक स्ट्रिंग शाब्दिक रूप में कोड उत्पन्न करने के लिए है, और एक mixin बयान यह मूल्यांकन करने के लिए:

import std.stdio, std.math; 

// CTFE function that generates trace code. 
string trace(string varName) { 
    return "writeln(\"" ~ varName ~ ": \", " ~ varName ~ ");"; 
} 

void main() { 
    // Trace a function call. 
    mixin(trace("sqrt(5)")); 

    // Trace a variable. 
    int foo = 5; 
    mixin(trace("foo")); 
} 

एकमात्र समस्या यह है कि मैन्युअल रूप से टाइपिंग mixin हर जगह वर्बोज़ है और जो कुछ भी आप ट्रेस करना चाहते हैं वह एक बदसूरत स्ट्रिंग शाब्दिक के अंदर होना चाहिए।

नोट डी खाका mixins में mixins बेहतर कई मायनों में व्यवहार किया जाता है, लेकिन स्ट्रिंग mixins (इस उदाहरण में प्रयुक्त) के दो प्रकार है कि किसी भी कोड में सिद्धांत रूप में कर सकते हैं के रूप में सामान्य रूप में यह हो जाता है के बारे में कर रहे हैं देखते हैं कि, सीटीएफई के माध्यम से उत्पन्न किया जाना चाहिए और फिर मिश्रित किया जाना चाहिए।

+0

बढ़िया! यही वही है जो मुझे चाहिए! धन्यवाद! उद्धरण आवश्यक सूक्ष्म है, है ना? बहुत खराब डी इसे क्लीनर को देखने के लिए varName को अलग करने की अनुमति नहीं देता है। मुझे अभिव्यक्ति को एक स्ट्रिंग के अंदर डालने में कोई फर्क नहीं पड़ता है (मैं अपने संपादक में सामान्य टोकन हिल्टिंग करने के लिए q {} का उपयोग कर सकता हूं)। Verbosity के रूप में, मैं एक बहुत ही कम समारोह नाम का उपयोग कर सकते हैं :-) – marcus

2

किसी भी लिस्प में ट्रिविअल। रैकेट में (उर्फ़ PLT योजना):

(define-syntax-rule (debug-info expr) 
    (format "~a is ~a" (quote expr) expr)) 

(let ((long-boring-name 5)) 
    (display (debug-info long-boring-name))) 

# displays "long-boring-name is 5" 

(let ((fifty-two 52)) 
    (display (debug-info (+ fifty-two 6)))) 

# displays "(+ fifty-two 6) is 58" 
0

मैं Tcl मूल रूप से विचार करें "लिस्प किसी भी डाटा संरचनाओं के बिना" (बजाय ... अच्छी तरह से तार, काफी कुछ भी, वास्तव में के साथ), तो यह लगभग Tcl में के रूप में आसान है लिस्प में

यह एक कुछ साल हो गया है, लेकिन मुझे लगता है कुछ इस तरह चाल करना होगा:

proc log_var {var} { 
    upvar 1 $var x 
    puts "$var is: $x" 
} 

set my_var 5 
log_var my_var 

मुझे लगता है कि शायद uplevel उपयोग करने के लिए इस विस्तार करने के लिए मनमाने ढंग से भाव के लिए काम करने के लिए एक तरीका है।

+0

मैं Tcl में पहले कभी नहीं प्रोग्राम किया था (मैं भाषा के बुनियादी वाक्यविन्यास पता किया था), लेकिन अपने सुझाव निम्नलिखित मैं इस के साथ आया था: proc log_expr {exp} { सेट एक्स [uplevel 1 $ exp] BREAK_LINE_HERE "$ exp है: $ x" } log_expr {expr 1 + 1} यह बहुत अच्छा है !!!! – marcus

संबंधित मुद्दे