Itcl Соответствующее возвращаемое значение configbody

Я хочу вернуться из configbody, но не могу сделать это явно без заставляя переменную не быть установленной.

Я хотел бы помочь понять поведение, которое я вижу. Обратите внимание на следующий код (с использованием Itcl 3.4):

package require Itcl
catch {itcl::delete class Model}
itcl::class Model {
    public variable filename "orig"
}

itcl::configbody Model::filename {
    if 1 {
        return ""
    } else {
    }
}

Model my_model
my_model configure -filename "newbie"
puts "I expect the result to be 'newbie:' [my_model cget -filename]"

Когда я возвращаю пустую строку, для имени файла не устанавливается новое значение. Если я не вернусь, а просто позволю процессу провалиться, имя файла изменится. Вы можете увидеть это, изменив 1 на 0 в приведенном выше коде.

Я подозреваю, что это связано со следующим утверждением:

Когда в сценарии нет возврата, его значением является значение последней команды, вычисленной в сценарии.

Если бы кто-нибудь объяснил это поведение и то, как я должен вернуться, я был бы признателен за помощь.


person Robert Lugg    schedule 23.06.2015    source источник


Ответы (1)


Tcl обрабатывает return, генерируя исключение (типа TCL_RETURN). Обычно внешняя часть обработчика процедуры или метода перехватывает это исключение и преобразует его в обычный результат процедуры/метода, но вы можете перехватить что-то с помощью catch и немного заглянуть внутрь.

Однако configbody не использует этот механизм. Он просто запускает скрипт в каком-то контексте (не знаю, в каком!), и этот контекст интерпретирует TCL_RETURN как указание на сбой обновления.

Обходной путь:

itcl::configbody Model::filename {
    catch {
        if 1 {
            return ""
        } else {
        }
    } msg; set msg
    # Yes, that's the single argument form of [set], which READS the variable...
}

Или вызовите реальный метод в configbody, передав любую необходимую информацию.

person Donal Fellows    schedule 24.06.2015