Я ищу независимую от контекста отложенную оценку закрытия. В псевдокоде:
// imagine there's a special type of "deferred" variables
$var = (deferred) function () {
// do something very expensive to calculate
return 42;
};
// do something else - we do not need to know $var value here,
// or may not need to know it at all
var_dump($var * 2);
// after some million years it prints: int(84)
// now this is the hardest part...
var_dump($var); // notice no brackets here
// prints immediately as we already know it: int(42)
Последний шаг имеет решающее значение: таким образом мы можем передать переменную (или члена класса) так, чтобы никто не знал, что это на самом деле, до того момента, когда они его используют.
Ясно, что я не могу сделать это прямо на языке, потому что даже со строками __toString()
магический метод не заменит первоначальное значение. Даже он не будет работать ни с чем, кроме строк:
// this will fail
function __toString()
{
return new Something();
}
Конечно, я могу обернуть Closure другим объектом, но это означает, что каждый, кто находится в стеке, должен знать, как с ним работать. И это то, чего я хочу избежать.
Возможно ли это хотя бы отдаленно? Может быть, есть где-нибудь хакерский PECL, чтобы сделать это или что-то подобное.
Я думаю, что вы хотите, это записки.
http://en.wikipedia.org/wiki/Memoization
Это одна из тех недокументированных возможностей в PHP. В основном вы объявляете статическую переменную в закрытие и использовать его как кеш.
$var = function(){
static $foo; // this is a memo, it sticks only to the closure
if (isset($foo)) return $foo;
$foo = expensive calculation
return $foo;
};
var_dump($var()); // millions of years
var_dump($var()); // instant
Это будет лениво оценивать и кэшировать вычисления.
Если вы имеете в виду «отложить», как при запуске их в фоновом режиме, вы не можете, потому что PHP не многопоточный. Вам придется настроить многопроцессорных рабочих или использовать pthreads.
Других решений пока нет …