Как получить результат из кода в опции -command - PullRequest
0 голосов
/ 05 июня 2018

ссылка: https://en.wikibooks.org/wiki/Tcl_Programming/Tk_examples#A_little_calculator

Я начинающий Tcl Language.Я попытаюсь сделать факториальную процедуру этим кодом калькулятора,

используя кнопку "!"

произошла ошибка, подобная этой:

invalid command name "if{x<2}"
invalid command name "if{x<2}"
    while executing
"if{x<2} {
 return 1
} else "
    (procedure "fac" line 2)
    invoked from within
"fac {$row}"
    invoked from within
".20 invoke"
    ("uplevel" body line 1)
    invoked from within
"uplevel #0 [list $w invoke]"
    (procedure "tk::ButtonUp" line 24)
    invoked from within
"tk::ButtonUp .20"
    (command bound to event)

и использование "!"в коде ошибки клавиатуры, как это

    wrong # args: should be "fac x"
    wrong # args: should be "fac x"
        while executing
    "fac"
        (command bound to event)

в этом коде

package require Tk
    wm title . Calculator
    grid [entry .e -textvar e -just right] -columnspan 5
    bind .e <Return> =
    bind .e <!> fac

    set n 0

    foreach row {
       {7 8 9 + -}
       {4 5 6 * /}
       {1 2 3 ( )}
       {C 0 . = !}
    } {
       foreach key $row { 
           switch -- $key {
               =       {set cmd =}
               C       {set cmd {set clear 1; set e ""}}
               !       {set cmd {[fac {$row}]}} 
               default {set cmd "hit $key"}
           }
           lappend keys [button .[incr n] -text $key -command $cmd]
       }
       eval grid $keys -sticky we ;#-padx 1 -pady 1
       set keys [list]
    }
    grid .$n -columnspan 2 ;# make last key (=) double wide
    proc = {} {
       regsub { =.+!} $::e "" ::e ;# maybe clear previous result
       if [catch {set ::res [expr [string map {/ *1.0/} $::e]]}] {
           .e config -fg red 
       }
       append ::e = $::res 
       .e xview end
       set ::clear 1
    }
    proc fac {x} {
    if{$x<2} {
     return 1
    } else 
    {
    return $x[fac[incr x-1]]
    }
    }

    # expr {$x<2? x 1: $x*[fac [incr x -1]]}}

    proc hit {key} {
       if $::clear {
           set ::e ""
           if ![regexp {[0-9().]} $key] {set ::e $::res}
           .e config -fg black
           .e icursor end
           set ::clear 0
       }
       .e insert end $key
    }
    set clear 0
    focus .e           ;# allow keyboard input
    wm resizable . 0 0

Итак, я не могу получить процедуру результата в -command или cmd.

Какполучить результат процедуры возврата, используя опцию cmd, -command в Tcl?

Извините, что трудно читать по-английски, спасибо.

PS Я думаю, что "cmd", скорее всего, другой язык (какС стилем) в "Макро"?

1 Ответ

0 голосов
/ 05 июня 2018

Ваша проблема в том, что это:

proc fac {x} {
if{$x<2} {
 return 1
} else 
{
return $x[fac[incr x-1]]
}
}

не вычисляет факториал.Да, она объявляет процедуру fac, но сценарий ее реализации неверен во многих отношениях, что равносильно синтаксическим ошибкам.Давайте сначала исправим очевидные места, где у вас пропущены пробелы или дополнительные символы новой строки:

proc fac {x} {
if {$x<2} {
 return 1
} else {
return $x[fac [incr x -1]]
}
}

Это теперь будет вычислять что-то (мы избавились от синтаксических проблем, добавивпробел между if и его первым аргументом, между x и -1 в аргументах incr, между fac и [incr …] в рекурсивном вызове и избавлением от дополнительного символа новой строки после else) но это все же не то, что вы хотите, так как оно не умножается $x на [fac [incr x -1]];добавление к этому (с [expr {… * …}]) дает нам это:

proc fac {x} {
if {$x<2} {
 return 1
} else {
return [expr {$x * [fac [incr x -1]]}]
}
}

Теперь у нас есть фактический функционал факториала!Давайте просто быстро исправим отступ для ясности:

proc fac {x} {
    if {$x<2} {
        return 1
    } else {
        return [expr {$x * [fac [incr x -1]]}]
    }
}

Существуют более эффективные способы реализации факториала, но, по крайней мере, сейчас это чистый рабочий пример.


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

Возможно, вы захотите найти и установить копию nagelfar tool .Это делает синтаксический анализ и найдет для вас все виды ошибок в коде.

...