Чисто теоретический вопрос на Tcl.
После этого вопроса я думал на том, что будет лучшим способом реализовать анонимные функции в Tcl.
Конечный результат должен позволять разработчику передавать полный proc как аргумент другому proc:
do_something $data {proc {} {input} {
puts $input;
}};
который был бы подобен JavaScript
do_something(data, function (input) {
alert(input);
});
теперь, естественно это не будет работать OOTB. Я думал на чем-то вроде этого вида:
proc do_something {data anon_function} {
anon_run $anon_function $data
}
proc anon_run {proc args} {
set rand proc_[clock clicks];
set script [lreplace $proc 1 1 $rand];
uplevel 1 $script;
uplevel 1 [concat $rand $args];
uplevel 1 rename $rand {}; //delete the created proc
}
Это работает. Но я надеялся получить предложения для лучшего шаблона затем это, поскольку это не очень изящно и не действительно использующие прохладные функции Tcl. Главным образом я хотел бы избавиться от ручного вызова anon_run
.
В Tcl 8.5 вы можете использовать команду apply
-.
proc do_something {data anon_function} {
apply $anon_function $data
}
do_something $data {{input} {
puts $input
}}
Конечно, если вы структурируете свои обратные вызовы как префиксы команд (рекомендуется!), то вы можете поступить следующим образом:
proc lambda {arguments body} {
# We'll do this properly and include the optional namespace
set ns [uplevel 1 namespace current]
return [list ::apply [list $arguments $body $ns]]
}
proc do_something {data command} {
{*}$command $data
}
do_something $data [lambda {input} {
puts $input
}]
Если вы используете 8.4 или более ранние версии, то вам пригодится код из Tcler's Wiki в качестве замены, но имейте в виду, что эти решения эквивалентны только семантически (в лучшем случае); они не эквивалентны по производительности.