Re: RFC: Nested enclosing returns
| From: | Rowan Collins | Date: | Sun, 22 Mar 2015 09:39:57 +0000 |
| Subject: | Re: RFC: Nested enclosing returns | ||
| References: | 1 2 3 4 5 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-85404@lists.php.net to get a copy of this message | ||
On 21 March 2015 17:55:32 GMT, "Georges.L" <contact@geolim4.com> wrote:
>To be honest I had not thought about the bad side of this use, i guess
>it
>could be possible to not return upper than a try/catch block (then
>return a
>fatal error if our code is trying to returns upper than a try/catch
>block).
>
>Now the practical example:
>
>// Code i have the hand on
>function main()
>{
> foo('bar');
> echo "I'm an angel !";
>}
>
>function bar()
>{
> echo "I'm not Evil";
>}
>
>//Code i don't have the hand on (like a MVC core)
>function foo($thing)
>{
> //
> make_love_dont_war();
> call_user_func($thing);
>
> //Do some stuff i don't want to execute
> echo 'evil';
>}
>
>function make_love_dont_war()
>{
> echo 'Make love, dont war.';
>}
>
>You get it ?
Not really, no. In this example, the code you want to skip happens to be all the code after
executing the callback, but what if there was some essential cleanup there, or the "evil"
line was before the callback, not after?
In general, a function should be a reusable, self-contained unit of code, and as such shouldn't
want to know about where it was called from. But in order to know how many levels to force to
return, you need to know how deeply nested you are, and the expected return type of the function
you're jumping out of, as well as which code you're bypassing by doing so. If someone
reuses the function, or refactors the calling code, some very confusing bugs will result.
Rather than "jump N levels up the call stack", what you maybe want is "jump up to
somewhere labelled X". This is sort of what exceptions do - they jump up the stack until they
find somewhere expecting to handle that condition. The function throwing the exception doesn't
know where it will be caught, so is not fragile to reuse or refactoring. However, using exceptions
for anything other than error handling is generally frowned upon, because they can lead to hard to
follow logic which would be better off refactored in plain procedural/OO style.
In your example, it's up to the maintainers of the foo() function (e.g. framework) to make the
"evil" optional, by passing in some additional setting, or allowing the callback to return
a special value, or just splitting the work in such a way that you can access the desired
functionality without calling foo() at all. If it's open source, you could submit a patch, or,
worst case, maintain a fork.
Regards,
--
Rowan Collins
[IMSoP]