Как напечатать имя переменной и ее значение, не вводя имя дважды? - PullRequest
6 голосов
/ 04 сентября 2010

Когда вы отлаживаете, очень полезно сделать это:

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

Есть ли язык, где это легко сделать?В C и C ++ вы можете использовать оператор stringify macro #, а в Ruby я нашел такой вопрос:

Ruby - выведите имя переменной и затем ее значение

Решениекоторый использует символ: var и блок - это то, что я хочу.

В D я использовал это:

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

Но я не уверен, что это лучший способ, потому что он работаеттолько в простых случаях.Я пробовал несколько способов, но иногда вы можете получить строку, но не значение (потому что переменные находятся вне области видимости), или вам сначала нужно смешать шаблон, а затем вызвать функцию.

А как насчетДругие языки?Python?F #?Бу?Сценарий оболочки (какая оболочка)?Perl?(Я предпочитаю держаться подальше от Perl, хотя)Tcl?Лисп, Схема?Джава?(крайне маловероятно, что Java сможет это сделать).

Даже в тех языках, где я нашел какое-то решение, оно работает только для простых случаев.Что если я хочу напечатать произвольное выражение?

Если бы я разрабатывал язык, эта функция была бы обязательной.: -)

Ответы [ 3 ]

5 голосов
/ 04 сентября 2010

Вот очень общий, но немного уродливый способ сделать это в D, используя оценку функции времени компиляции (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 везде является многословным, и все, что вы хотите отследить, должно быть внутри уродливого строкового литерала.

Обратите внимание, что в D. есть два вида миксинов. Шаблонные миксины лучше ведут себя во многих отношениях, но строковые миксины (используемые в этом примере) примерно такие же общие, как в этом любом коде в принципе может генерироваться через CTFE и затем смешиваться.

2 голосов
/ 04 сентября 2010

Тривиально в любом Лиспе.В ракетке (схема 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 голосов
/ 04 сентября 2010

Я считаю, что Tcl в основном "Lisp без каких-либо структур данных" (со строками вместо ... ну, почти все, на самом деле), поэтому в Tcl это почти так же просто, как в Lisp.

Это былопару лет, но я думаю, что-то вроде этого поможет:

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

set my_var 5
log_var my_var

Я думаю, что, вероятно, есть способ использовать uplevel, чтобы расширить это для работы с произвольными выражениями.

...