Tcl анонимные функции - PullRequest
7 голосов
/ 13 июля 2010

Чисто теоретический вопрос по Tcl.

После этого вопроса Я думал о том, как лучше реализовать анонимные функции в Tcl.

Конечный результат должен позволять разработчику передавать полный процесс в качестве аргумента в процесс anohter:

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.

1 Ответ

12 голосов
/ 13 июля 2010

В 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 в качестве замены, но помните, что эти решения семантически эквивалентны (в лучшем случае); они не эквивалентны производительности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...