2014-09-25 2 views
4

В чем разница между кадрами и уровнями исполнения?Tcl: [info level] vs. [info frame]

Я написал небольшой пример, чтобы узнать. Я понял, что номер уровня увеличивается каждый раз, когда вызывается proc.

С другой стороны, номер кадра был увеличен на каждом

  • Proc вызова
  • команда источник
  • Eval команда
  • т.д.

По этой причине, я начал думать о уровнях как о подмножестве кадров. Теперь я отлаживаю какой-то реальный код, и я понял, что номер уровня может увеличиться без увеличения числа кадров. Как понять этот материал?

ответ

4

Уровни стека, о которых говорят info level, являются важными, потому что это те, которые вы можете использовать upvar и uplevel для доступа. Это означает, что Tcl «stack» равен действительно дерево, так как вы можете использовать uplevel, чтобы перейти на более высокий уровень и начать новую ветку, причем каждый шаг глубже принимается вызовом процедуры (или процедурной вещь) или по телефону namespace eval; команда info level действительно говорит о текущей ветке, прослеживаемой вплоть до корня.

Команда info frame ходит по дереву кадров, а по-другому - я думаю, что он использует фактический путь, в котором они сложены, с кадрами в состоянии дважды появляться - и отчеты очень разная информация о каждом из этих кадров. Лично я только нахожу, что это полезно для отладки.

Давайте попробуем простой пример. Это интерактивный сеанс.

% proc foo {y} {set x 1;bar $y $x $y} 
% proc bar {a b args} { 
    puts [info level 0] 
    puts [info level -1] 
    puts [info frame 0] 
    puts [info frame -1] 
} 
% foo 3 
bar 3 1 3 
foo 3 
type proc line 4 cmd {info frame 0} proc ::bar level 0 
type proc line 1 cmd {bar $y $x $y} proc ::foo level 1 

ОК, как вы можете видеть, info level сообщает фактические значения, которые были использованы и не сообщать о себе, в то время как info frame сообщает, что этот уровень в настоящее время делает.

Вот более сложный пример:

% proc foo {y} {set x 1;grill $y $x $y} 
% proc grill {a b c} {uplevel 1 [list bar $a $b $c]} 
% proc bar {args} { 
    for {set i 1} {$i<=[info level]} {incr i} {puts $i-->[info level $i]} 
    for {set i 1} {$i<=[info frame]} {incr i} {puts $i==>[info frame $i]} 
} 
% foo 3 
1-->foo 3 
2-->bar 3 1 3 
1==>type eval line 1 cmd {foo 3} level 2 
2==>type proc line 1 cmd {grill $y $x $y} proc ::foo level 1 
3==>type proc line 1 cmd {uplevel 1 [list bar $a $b $c]} proc ::grill 
4==>type eval line 1 cmd {bar 3 1 3} proc ::grill 
5==>type proc line 3 cmd {info frame $i} proc ::bar level 0 

Как вы можете видеть, info levelне видит что uplevel произошло, но info frameделает. Но только info level действительно может рассказать вам, что такое аргументы. (Обратите внимание, что если вы поместите код в файл, который вы source, info frame сообщает еще больше информации.)