class typeFunction EXTENDS Tuple { CONST func = 0x00; CONST args = 0x01; CONST expected = 0x02; function __construct(array $__define = []) { $defined = [ self::func => \ILLI\Std\Def\constType::SPL_CLOSURE, self::args => \ILLI\Std\Def\constType::SPL_TUPLE, self::expected => \ILLI\Std\Def\constType::SPL_INTEGER ]; $define = $this->mergeTypes($defined, $__define); parent::__construct($define); } function __invoke() { $F = $this[self::func]; $r = $F(); if(FALSE === $this->offsetValidate(self::expected, $r)) throw new Exception('<<{:r}>{:f}>{:c}: result is <{:t}>{:s}.', [ 't' => $t = getType($r), 's' => is_object($r) ? get_class($r) : (is_string($r) && (class_exists($r) || interface_exists($r)) ? $r : (is_scalar($r) ? $r : $t)), 'c' => $this->getName(), 'f' => implode('|', $this->offsetGetTypeDef(self::func)), 'r' => implode('|', $this->offsetGetTypeDef(self::expected)) ]); return $r; } } $f = new typeFunction; $f->func = function() { return '4'; }; var_dump($f()); TRACK OUTER [UNSOLVED] <closure>root\typeFunction: result is 4. NHADDR NULL PHADDR NULL CHADDR 000000005cf1508b0000000000e956e6: SYADDR /var/www/dev/__MAIN__.ddl, line 69 RVADDR 0x01f4: line 0088 /var/www/dev/__MAIN__.ddl root\typeFunction->__invoke CHADDR 000000005cf1508b0000000000e956e6 ECADDR 500 RVADDR OUTER 000000005cf1508b0000000000e956e6: [UNSOLVED] <closure>root\typeFunction: result is 4. SET CLASS: ILLI\Std\Exception CH: 000000005cf1508b0000000000e956e6 CHADDR: 000000005cf1508b0000000000e956e6 ECADDR: 500 STATUS: UNSOLVED MESSAGE: "<closure>root\\typeFunction: result is 4." CODE: 500 FILE: /var/www/dev/__MAIN__.ddl LINE: 69