Passed
Push — master ( 66b084...e36ead )
by Radosław
02:43
created

invoker()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace phln\fn;
5
6
use function phln\fn\curryN;
7
8
const invoker = '\\phln\\fn\\invoker';
9
const 𝑓invoker = '\\phln\\fn\\𝑓invoker';
10
11
/**
12
 * Turns a named method with a specified arity into a function that can be called directly supplied with arguments and a target object.
13
 *
14
 * The returned function is curried and accepts `arity + 1` parameters where the final parameter is the target object.
15
 *
16
 * @phlnSignature Int -> String -> (a -> b -> c -> ... -> n -> Object -> *)
17
 * @phlnCategory function
18
 * @since 1.2.0
19
 * @param int $arity
20
 * @param string $method
21
 * @return \Closure
22
 * @example
23
 *      $greeter = new class ()
24
 *      {
25
 *          public function hello($name, $lastname)
26
 *          {
27
 *              return "Hello, {$name} {$lastname}!";
28
 *          }
29
 *      };
30
 *
31
 *      $helloToJon = \phln\fn\invoker(2, 'hello')('Jon');
32
 *      $helloToJon('Snow'); // 'Hello, Jon Snow!'
33
 */
34
function invoker(int $arity = null, string $method): \Closure
35
{
36
    return curryN(2, 𝑓invoker, func_get_args());
37
}
38
39
function 𝑓invoker(int $arity, string $method): \Closure
40
{
41
    $wrapper = function(...$args) use ($arity, $method) {
42
        $args = array_slice($args, 0, $arity + 1);
43
        $object = array_pop($args);
44
45
        assert(is_object($object));
46
47
        return $object->$method(...$args);
48
    };
49
50
    return curryN($arity + 1, $wrapper);
51
}
52