Shorthand to invoke the callable just once (when needed) and return its result afterwards.
@param callable $callable
@param array $args
@return callable
177687
public function once(callable $callable, array $args = [])
    {
        return function () use ($callable, $args) {
            static $result;
            if (!$result) {
                $result = $this->invoke($callable, $args);
            }
            return $result;
        };
    }
1129905
protected function callListener($callable, Event $event)
    {
        if ($callable instanceof Closure || is_array($callable)) {
            call_user_func_array($callable, array_filter([$event, $event->getSubject(), $event->getData()]));
        } elseif (is_object($callable)) {
            $callable->{$event->getType()}($event, $event->getSubject(), $event->getData());
        }
    }
307036
public static function mapRecursive($iterable, callable $callable): array
    {
        Assert::isIterable($iterable);

        // If internal method with one arg, like strtolower, limit to first arg so warning isn't triggered.
        $ref = new \ReflectionFunction($callable);
        if ($ref->isInternal() && $ref->getNumberOfParameters() === 1) {
            $callable = function ($arg) use ($callable) {
                return $callable($arg);
            };
        }

        return static::doMapRecursive($iterable, $callable);
    }
879265
private function validCallable($callable)
    {
        if (is_callable($callable)) {
            if ($callable instanceof \Closure) {
                $callable = $callable->bindTo($this->container);
            }

            return $callable;
        } elseif (is_string($callable) && count(explode(':', $callable)) == 2) {
            return $callable;
        }

        $this->addedExceptions['\InvalidArgumentException'] = 'Callable inválido';
        return false;
    }
755183
protected function callListener(callable $listener, array $args = [])
    {
        switch (count($args)) {
            case 0:
                return call_user_func($listener);
            case 1:
                return call_user_func($listener, $args[0]);
            case 2:
                return call_user_func($listener, $args[0], $args[1]);
            case 3:
                return call_user_func($listener, $args[0], $args[1], $args[2]);
            case 4:
                return call_user_func($listener, $args[0], $args[1], $args[2], $args[3]);
        }

        return call_user_func_array($listener, $args);
    }
127074
public static function invokeCallable($callable, $args = null)
    {
        if (null != $args) {
            if (is_array($args)) {
                $results = call_user_func_array($callable, $args);
            } else {
                $results = call_user_func($callable, $args);
            }
        } else {
            $results = call_user_func($callable);
        }

        return $results;
    }
67583
public function invoke($callable, $arguments = []): self
    {
        // If one argument given for each iteration, create an array for it.
        if (!\is_array($arguments)) {
            $arguments = \array_fill(
                0,
                \count($this->getArray(), \COUNT_NORMAL),
                $arguments
            );
        }

        // If the callable has arguments, pass them.
        if ($arguments) {
            $array = \array_map($callable, $this->getArray(), $arguments);
        } else {
            $array = $this->map($callable);
        }

        return static::create(
            $array,
            $this->iteratorClass,
            false
        );
    }
624027
public static function callFast(callable $callable, $args=null)
    {

        if (!is_array($args)) {
            return call_user_func($callable, $args === null ? [] : [$args]);
        }

        switch (count($args)) {
            case 0:
                return call_user_func($callable);
            case 1:
                return call_user_func($callable, $args[0]);
            case 2:
                return call_user_func($callable, $args[0], $args[1]);
            case 3:
                return call_user_func($callable, $args[0], $args[1], $args[2]);
            case 4:
                return call_user_func($callable, $args[0], $args[1], $args[2], $args[3]);
        }

        return call_user_func_array($callable, $args);
    }
776454
public static <V> Try<V> tryCall(Callable<V> callable) {
        try {
            return Try.succeeded(callable.call());
        } catch (Exception e) {
            return Try.failed(e);
        }
    }
443175
protected function getCallableParameters(callable $callable)/*# : array */
    {
        // array type
        if (is_array($callable)) {
            $reflector = new \ReflectionClass($callable[0]);
            $method = $reflector->getMethod($callable[1]);

        // object with __invoke() defined
        } elseif ($this->isInvocable($callable)) {
            $reflector = new \ReflectionClass($callable);
            $method = $reflector->getMethod('__invoke');

        // simple function
        } else {
            $method = new \ReflectionFunction($callable);
        }

        return $method->getParameters();
    }
327191
public function share(Closure $callable) : Closure
    {
        return function () use ($callable) {
            static $object;
            $c = $this;

            if (is_null($object) && $callable instanceof Closure) {
                $object = $callable($c);
            }

            return $object;
        };
    }
981054
protected function once(callable $callable, $udId = null)
    {
        if (!$udId)
        {
            $udId = $this->hash($callable);
        }

        return $this->objectBuild($udId, $callable);
    }
564215
public static function multiply(callable ...$args): callable
    {
        $product = function ($x, ... $args) {
            $function = 1;
            foreach ($args as $arg) {
                $function *= $arg($x);
            }
            return $function;
        };

        return function ($x) use ($args, $product) {
            return $product(...array_merge([$x], $args));
        };
    }
1037037
protected function callListener(callable $listener, $event, array $args)
    {

        if (!$this->marks) {
            return Lambda::callFast($listener, $args);
        }

        if ($listener instanceof MatchingListener) {
            return $listener->callWithMarks($args, $this->marks);
        }

        return Lambda::callFast($listener, $args);

    }
410786
function then(/*callable*/ $callable = null, /*callable*/ $failure = null)
    {
        if ($failure !== null)
            $this->onFailure($failure);

        if ($callable === null)
            return $this;
        
        
        if (! is_callable($callable) )
            throw new \Exception(sprintf(
                'The argument given is not callable; given: (%s).'
                , \Poirot\Std\flatten($callable)
            ));


        try {
            $result = call_user_func($callable, $this->collector(), $this);
        } catch(\Exception $e) {
            if ($this->failure)
                return call_user_func($this->failure, $e, $this);

            throw $e;
        }
        
        $this->then = $callable;
        return $result;
    }
1306728
public function execute(callable $function, array $arguments = [])
    {
        $delayFunction = $this->delayFunction;
        $retryAttempt = 0;

        $continue = true;
        do {
            try {
                $res = call_user_func_array($function, $arguments);
                $continue = false;
                return $res;
            } catch (\Exception $exception) {
                if ($this->retryFunction) {
                    if (!call_user_func($this->retryFunction, $exception)) {
                        throw $exception;
                    }
                }

                if ($retryAttempt < $this->retries) {
                    $delay = $delayFunction($exception);
                    $delay += [
                        'seconds' => 0,
                        'nanos' => 0
                    ];

                    time_nanosleep($delay['seconds'], $delay['nanos']);

                    $retryAttempt++;
                } else {
                    $continue = false;
                    throw $exception;
                }
            }
        } while ($continue);
    }
586873
public static function call($cb, array $args = [])
    {
        if (!$cb) {
            return true;
        }

        if (\is_array($cb)) {
            [$obj, $mhd] = $cb;

            return \is_object($obj) ? $obj->$mhd(...$args) : $obj::$mhd(...$args);
        }

        if (\is_string($cb)) {
            if (\function_exists($cb)) {
                return $cb(...$args);
            }

            // a class name
            if (\class_exists($cb)) {
                $cb = new $cb;
            }
        }

        // a \Closure or Object implement '__invoke'
        if (\is_object($cb) && \method_exists($cb, '__invoke')) {
            return $cb(...$args);
        }

        throw new \InvalidArgumentException('the callback handler is not callable!');
    }