Edit report at https://bugs.php.net/bug.php?id=77091&edit=1
ID: 77091
Comment by: a at b dot c dot de
Reported by: asmqb7 at gmail dot com
Summary: Using debug_backtrace() to distinguish continuations
called on the same line
Status: Open
Type: Feature/Change Request
Package: Scripting Engine problem
Operating System: All
PHP Version: 7.2.11
Block user comment: N
Private report: N
New Comment:
I suppose in the meantime a workaround could be writing
<?php
$z->z()
->z()
->z();
?>
(P.S. What is written here is just method chaining (maybe "fluent"); I know it's just
for illustration but it's not in continuation-passing style).
Previous Comments:
------------------------------------------------------------------------
[2018-10-31 22:30:07] asmqb7 at gmail dot com
Description:
------------
Hi,
While working to add some robustness to a debug helper library I stumbled on a "fun"
little edge-case scenario that may arise due to the increasing popularity of continuation-passing
style programming.
I unfortunately suspect it will be a bit tricky to fix in the shorter term, so I'm adding this
bug to document the existence of the following in the hope that it can be factored into future
design decisions.
--
Consider a scenario where the same continuation function is called multiple times. For example, a
setter function:
$blah->setValue()->setValue()->setValue();
I agree that patterns using the same function name can be a tad awkward, but entirely plausible to
find being used in real-world scenarios (I unfortunately have no citable examples I can list).
Now, in theory, each of those setValue() calls might be doing something appropriately contained to
the scope of $blah, but nonetheless sufficiently nontrivial that I might want to inspect the state
of $blah at each setValue() call site.
Here's the problem: it's not possible for me to determine which setValue() call I'm
in. I have to rely on examination of function arguments or other context in order to figure things
out.
--
The included test script demonstrates this.
- It generates a backtrace, stores it, and if it's the same as the last backtrace, it prints
"same".
- The script prints one backtrace then prints "same" twice because the other two collected
backtraces are completely identical.
I strongly argue that some mechanism other than line numbers is needed to identify which function is
being executed. (Particularly considering that the line numbers PHP reports are inaccurate.)
It may sound like overkill, but something similar to token_get_all() that folds
currently-executing-function annotation metadata into the returned token stream would be pretty
awesome and would completely solve this and probably many other issues.
Test script:
---------------
<?php
class x {
function z() {
$bt = debug_backtrace();
global $oldbt;
if ($bt == $oldbt) {
print "same\n";
} else {
print_r($bt);
}
$oldbt = $bt;
return $this;
}
}
$z = new x();
$z->z()->z()->z();
Expected result:
----------------
I'm not going to impose any specific interpretation; any solution that allows me to determine
exactly which function I'm in regardless of line number will be highly appreciated.
Actual result:
--------------
Array
(
[0] => Array
(
[file] => test.php
[line] => 19
[function] => z
[class] => x
[object] => x Object
(
)
[type] => ->
[args] => Array
(
)
)
)
same
same
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=77091&edit=1