https://github.com/cyber-duck/fluent-debug
Helper for using xDebug breakpoints with method/function chaining
https://github.com/cyber-duck/fluent-debug
breakpoints debugging laravel php xdebug
Last synced: about 1 year ago
JSON representation
Helper for using xDebug breakpoints with method/function chaining
- Host: GitHub
- URL: https://github.com/cyber-duck/fluent-debug
- Owner: Cyber-Duck
- License: mit
- Created: 2017-02-04T17:44:33.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2023-09-08T11:20:51.000Z (almost 3 years ago)
- Last Synced: 2024-10-31T13:28:56.665Z (over 1 year ago)
- Topics: breakpoints, debugging, laravel, php, xdebug
- Language: PHP
- Homepage:
- Size: 5.86 KB
- Stars: 2
- Watchers: 5
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# 🚨 Discontinued 🚨
This package will no longer be supported.
# Fluent / Chaining Methods/ Functions xDebug Library
##Why?
Frameworks like Laravel make heavy usage of, and encourage, method chaining
Consider code like the following random line taken from Laravel framework:
```
Finder::create()
->files()
->name('*.php')
->in($configPath)
```
That looks lovely. But there's a problem. Suppose I'm interested in the return value of
```
Finder::create()
->files()
->name('*.php')
```
and I wish to examine this in a debugger.
At present, the only way I'm aware of doing this in PHP[1](#myfootnote1)
with xDebug is either to step through it, or to tediously rewrite the code to
introduce intermediate variables, i.e. rewrite the above to
```
$a = Finder::create()
->files()
->name('*.php')
//put breakpoint on this line:
$a->in($configPath)
```
which doesn't sound particularly difficult in this example but soon becomes a massive mess.
Let's consider another random line:
```
Chicken::load(meatProcess($sausage->bacon()));
```
Suppose I'm interested in the return value of `$sausage->bacon()` here. Where do I stick a breakpoint to get that?
If I put it on the line, I have to step through the call to `bacon` and intercept the return value, which is sometimes rather difficult.
Or perhaps I can put the breakpoint on the first line of the call to `meatProcess`. A third option is to do something
like
```
Chicken::load(meatProcess(($a = $sausage->bacon())->ketchup()));
$a;
```
And put a breakpoint on the second line. But suppose the call to `ketchup` has altered `$a`? You're going to be misled!
And in any case, I'm messing up the code again.
This kind of thing is why some programmers are against method chaining in general - the debugging really is made much harder.
See for example https://ocramius.github.io/blog/fluent-interfaces-are-evil/
But we live in the real world and it's a popular way of doing things, and done well as with Laravel it makes your code
so much simpler to read.
##How?
So here I present a very simple extension that I believe takes out the vast majority of the debugging pain caused by fluent
method chaining.
The extension is in two parts. Firstly, there is a trait with two methods. `debugBreak` and `debugBreakIf`. These are
essentially wrappers around the `xdebug_break` function installed with xdebug.
Usage is like:
```
Finder::create()
->files()
->name('*.php')
->debugBreak()
->in($configPath)
```
or perhaps:
```
Finder::create()
->files()
->name('*.php')
->debugBreakIf(2 === $a)
->in($configPath)
```
or indeed:
```
Finder::create()
->files()
->name('*.php')
->debugBreakIf(function(){return app()->isRunningUnitTests();))
->in($configPath)
```
To use this, add `use CyberDuck\Traits\DebugsFluently` to any class where you wish to use it (or possibly its parent).
On my ever increasing todo list is a plan to write something that will add this to every class for you automatically.
Secondly - primarily intended for usage in function chaining - are the global functions `debugBreak` and `debugBreakIf`.
The above example would become
```
Chicken::load(meatProcess(debugBreak($sausage->bacon())->ketchup()));
```
Or there is `debugBreakIf` - The second argument works in the same way as the `debugBreakIf` method in the trait.
###Footnotes
1: There is a way in .NET - see https://davefancher.com/2016/01/28/functional-c-debugging-method-chains/