parser

Написать ответ на текущее сообщение

 

 
   команды управления поиском

$calller нужен для удобной организации замыканий...

Sumo 10.12.2014 09:19 / 10.12.2014 09:32

Т.е. для функций вида ^func[var;...]{code}. Самые распространенные случаи, когда это нужно — итераторы и обертки над ресурсами (примерный аналог оператора with в Питоне).

В документации приводится пример метода-итератор steppedfor:
@steppedfor[name;from;to;step;code]
$caller.$name($from)
^while($caller.$name<=$to){
   $code
   ^caller.$name.inc($step)
}
В данном случае мы делаем так, чтобы код, который записан в контексте вызывающего метода получил доступ к переменной-счетчику, которую мы итерируем в steppedfor. Для этого мы записываем значение счетчика в контекст вызывающей функции через caller.

Вариант замыканий для работы с ресурсами:
@tempFile[aPath;aVarName;aCode][lTempFileName]
## Формирует на время выполнения кода aCode уникальное имя для временного
## файла в папке aPath. После работы кода удаляет временный файл, если он создан.
  ^pfAssert:isTrue(def $aVarName)[Не задано имя переменной для названия временного файла.]
  ^try{
    $lTempFileName[^aPath.trim[end;/\]/${status:pid}_^math:uid64[].tmp]
    $caller.[$aVarName][$lTempFileName]
    $result[$aCode]
  }{}{
     ^if(-f $lTempFileName){
       ^file:delete[$lTempFileName]
     }
  }
http://code.volchkov.net/parser3-pf/src/9978cc47944d17d69c19652c6ae5d02816b56926/io/pfOS.p?at=pf

В этом примере мы в переменную вызывающего метода кладаем имя временного файла, которое нужно коду для работы.

Фактически caller — это вспомогательный механизм для того, чтобы получить доступ к контексту кода, который мы определили в вызывающем методе, но передали в нашу функцию.

Тонкий момент: и код (junction-code) и его контекст «живут» только до того момента, пока работает функция в которой этот код написан. Попытка сохранить код во внешнюю переменную и выполнить его позже приведет к ошибке.