rfc:callable-interfaces
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
rfc:callable-interfaces [2016/04/06 11:20] – ocramius | rfc:callable-interfaces [2017/09/22 13:28] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 4: | Line 4: | ||
* Author: Ben Scholzen, mail@dasprids.de | * Author: Ben Scholzen, mail@dasprids.de | ||
* Author: Marco Pivetta, ocramius@gmail.com | * Author: Marco Pivetta, ocramius@gmail.com | ||
- | * Status: | + | * Status: |
* First Published at: http:// | * First Published at: http:// | ||
Line 15: | Line 15: | ||
===== Proposal ===== | ===== Proposal ===== | ||
- | PHP already has a way to define objects that act as functions. That mechanism is the < | + | PHP already has a way to define objects that act as functions. That mechanism is the **_****_invoke** |
- | < | + | **_****_****invoke** |
<code php> | <code php> | ||
- | interface RegisterUser | + | interface RegisterUser { |
- | { | + | |
public function __invoke(Username $username) : UserRegistration; | public function __invoke(Username $username) : UserRegistration; | ||
} | } | ||
</ | </ | ||
- | We can now implicitly implement this interface by just defining any < | + | We can now implicitly implement this interface by just defining any *callable* that matches this interface: |
Line 52: | Line 51: | ||
<code php> | <code php> | ||
- | class Register | + | class Register { |
- | { | + | |
public static function register(Username $username) : UserRegistration { | public static function register(Username $username) : UserRegistration { | ||
// ... domain logic here ... | // ... domain logic here ... | ||
Line 67: | Line 65: | ||
<code php> | <code php> | ||
- | class Register | + | class Register { |
- | { | + | |
public function register(Username $username) : UserRegistration { | public function register(Username $username) : UserRegistration { | ||
// ... domain logic here ... | // ... domain logic here ... | ||
Line 89: | Line 86: | ||
</ | </ | ||
- | In order for this to work, any implicitly defined callable should be cast to a < | + | In order for this to work, any implicitly defined callable should be cast to a *Closure* at call-time. |
+ | |||
+ | In pseudo-code, | ||
+ | |||
+ | < | ||
+ | function passAParameterToAPhpFunction(callable $callable, $expectedParameterInterface) { | ||
+ | if (! $expectedParameterInterface-> | ||
+ | passParameter($callable); | ||
+ | |||
+ | return; | ||
+ | } | ||
+ | |||
+ | if (! $expectedParameterInterface-> | ||
+ | throw new TypeError(' | ||
+ | } | ||
+ | |||
+ | if (! is_object($callable)) { | ||
+ | $callable = wrapInCompatibleAnonymousClass($callable); | ||
+ | } | ||
+ | |||
+ | passParameter($callable); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== Still Open for Discussion ===== | ||
+ | |||
+ | How will **instanceof** behave, when asked for a type-check against **callable**? | ||
+ | |||
+ | <code php> | ||
+ | interface RegisterUser { | ||
+ | public function __invoke(Username $username) : UserRegistration; | ||
+ | } | ||
+ | |||
+ | interface DeleteUserRegistration { | ||
+ | public function __invoke(Username $username) : UserRegistration; | ||
+ | } | ||
+ | |||
+ | $register = function (Username $username) : UserRegistration { | ||
+ | return new UserRegistration(...); | ||
+ | }; | ||
+ | |||
+ | var_dump($register instanceof DeleteUserRegistration); | ||
+ | </ | ||
+ | |||
+ | ===== Retired ===== | ||
+ | |||
+ | This RFC has been retired. Reason for that is that PHP currently (Version 7.0~7.1) allows applying function semantics to objects via the **_****_invoke** magic methods. Allowing the opposite would mix the domain of functions and objects in ways that are very hard to disentangle, | ||
+ | |||
+ | While it is unfortunate that migration to type-safe callables (https:// | ||
===== Backward Incompatible Changes ===== | ===== Backward Incompatible Changes ===== |
rfc/callable-interfaces.1459941633.txt.gz · Last modified: 2017/09/22 13:28 (external edit)