As per recent discussions on Twitter, we are back to 2012, when I was still trying to build interceptor proxies with the __call() magic method approach. Evidently, people never learn that this approach isn't safe, and while it seems to save you time, it actually makes things harder to understand and debug when incompatible method calls happen.
An article could be needed, where following concepts are cleared up:
In an object oriented world, each object just has a public receive(Call $command) : Response; method, and only that method
Type safety is ensured by either compile- or runtime-checking of the $command and Response
Type-safety is really orthogonal to the OOP design, as well as optional. It is an anti-corruption layer for our commands and responses
It is possible to write generic middle-man objects, but duplicating the type checking efforts makes for easier to understand error messages both at compile and runtime
Duplicating the checking can be done via type inference or by adding some trickery upfront
Show how Gorilla#eat(Banana $banana) : bool; is Gorilla#receive(EatBanana $command) : StillHungry;, which can be wrapped with a generic LogAround#receive(Command $command) : Result
Show unsafe operations in the above
Re-convert the above to traditional PHP object signatures with methods
Show the possible failures also there
"Type check escapes" lead to unknown message types reaching the recipient, which now has to deal with them (additional work) or crash or do unexpected operations (security issue)
Show that it is possible to build a minimalist wrapper that builds a type-safe logger around a Gorilla
Show failures with the safer approach, show introspection failures too (maybe reflection?)
Conclusion: __call could work, but is not an anti-corruption layer due to its generic signature
99% of users will always benefit from proactive anti-corruption layers via AOT- or runtime- type checks
As per recent discussions on Twitter, we are back to 2012, when I was still trying to build interceptor proxies with the
__call()
magic method approach. Evidently, people never learn that this approach isn't safe, and while it seems to save you time, it actually makes things harder to understand and debug when incompatible method calls happen.An article could be needed, where following concepts are cleared up:
public receive(Call $command) : Response;
method, and only that method$command
andResponse
Gorilla#eat(Banana $banana) : bool;
isGorilla#receive(EatBanana $command) : StillHungry;
, which can be wrapped with a genericLogAround#receive(Command $command) : Result
Gorilla
__call
could work, but is not an anti-corruption layer due to its generic signature