On 4/19/16 10:02 AM, Rowan Collins wrote:
Dmitry Stogov wrote on 19/04/2016 15:48:
callable-type is much simpler solution for this use-case.
Usage of Interfaces to check function prototypes is a bit tricky, but yes, this is a possible use-case. Do you like to work with framework, that use this trick for every callback?

If you don't use __invoke as the function name, you can have a single class implement multiple contracts, e.g. to register for more than one event type with different signatures.

I guess if you had callable-types *and* union types, you could get the best of both worlds:

interface UserEventCallbackInterface {
    public function handleUserEvent(UserEvent $event): boolean;
}
public function registerCallback(EventCallbackInterface|callable(Event): boolean $handler) { ... }

The implementation has to be a bit fiddlier here, because you need to sometimes call $handler->handleUserEvent($event) and sometimes $handler($event); with a functional interface, the engine makes $handler->handleUserEvent($event) work for you. The cost is that the call site has to be a bit more verbose to specify the interface, rather than implicitly meeting the contract.

Regards,

Which is why I'm not sure I like that approach, because the place I then call $handler needs to have a conditional in it. There's another RFC that was posted to Twitter but hasn't made it to the list yet that seems to solve this better:

https://wiki.php.net/rfc/callable-types

(My apologies to the authors if they aren't done with it; it's on the wiki so I'm assuming it's safe to mention in public.)

That allows just the callable-type syntax (which I presume is what you're referencing), but you can then pass an object in using []-callable syntax: [$handler. 'handleUserEvent'], and then registerCallback() doesn't care if it was a function, method, closure, or whatever else. It can just () it.

--
--Larry Garfield


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to