{"id":19225020,"url":"https://github.com/cyber-duck/fluent-debug","last_synced_at":"2025-04-21T00:31:53.029Z","repository":{"id":56960556,"uuid":"80936413","full_name":"Cyber-Duck/fluent-debug","owner":"Cyber-Duck","description":"Helper for using xDebug breakpoints with method/function chaining","archived":false,"fork":false,"pushed_at":"2023-09-08T11:20:51.000Z","size":6,"stargazers_count":2,"open_issues_count":0,"forks_count":2,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-10-31T13:28:56.665Z","etag":null,"topics":["breakpoints","debugging","laravel","php","xdebug"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Cyber-Duck.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-02-04T17:44:33.000Z","updated_at":"2021-10-26T09:52:12.000Z","dependencies_parsed_at":"2022-08-21T09:20:57.326Z","dependency_job_id":null,"html_url":"https://github.com/Cyber-Duck/fluent-debug","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cyber-Duck%2Ffluent-debug","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cyber-Duck%2Ffluent-debug/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cyber-Duck%2Ffluent-debug/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cyber-Duck%2Ffluent-debug/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Cyber-Duck","download_url":"https://codeload.github.com/Cyber-Duck/fluent-debug/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223842137,"owners_count":17212323,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["breakpoints","debugging","laravel","php","xdebug"],"created_at":"2024-11-09T15:13:47.114Z","updated_at":"2024-11-09T15:13:47.821Z","avatar_url":"https://github.com/Cyber-Duck.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🚨 Discontinued 🚨\nThis package will no longer be supported.\n\n# Fluent / Chaining Methods/ Functions xDebug Library\n\n##Why?\n\nFrameworks like Laravel make heavy usage of, and encourage, method chaining\n\nConsider code like the following random line taken from Laravel framework: \n\n```\nFinder::create()\n-\u003efiles()\n-\u003ename('*.php')\n-\u003ein($configPath) \n\n```\n\nThat looks lovely. But there's a problem. Suppose I'm interested in the return value of\n\n```\nFinder::create()\n-\u003efiles()\n-\u003ename('*.php')\n```\n\nand I wish to examine this in a debugger.\n\nAt present, the only way I'm aware of doing this in PHP\u003csup\u003e[1](#myfootnote1)\u003c/sup\u003e\n with xDebug is either to step through it, or to tediously rewrite the code to \n introduce intermediate variables, i.e. rewrite the above to\n ```\n $a = Finder::create()\n -\u003efiles()\n -\u003ename('*.php')\n \n //put breakpoint on this line:\n $a-\u003ein($configPath) \n \n ```\n\nwhich doesn't sound particularly difficult in this example but soon becomes a massive mess.\n\nLet's consider another random line:\n\n```\nChicken::load(meatProcess($sausage-\u003ebacon()));\n```\n\nSuppose I'm interested in the return value of `$sausage-\u003ebacon()` here. Where do I stick a breakpoint to get that?\nIf 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. \nOr perhaps I can put the breakpoint on the first line of the call to `meatProcess`. A third option is to do something\nlike \n\n\n```\nChicken::load(meatProcess(($a = $sausage-\u003ebacon())-\u003eketchup()));\n$a;\n```\n\nAnd put a breakpoint on the second line. But suppose the call to `ketchup` has altered `$a`? You're going to be misled!\n\nAnd in any case, I'm messing up the code again.\n\nThis kind of thing is why some programmers are against method chaining in general - the debugging really is made much harder.\n\nSee for example https://ocramius.github.io/blog/fluent-interfaces-are-evil/\n\nBut 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\nso much simpler to read.\n\n##How?\n\nSo here I present a very simple extension that I believe takes out the vast majority of the debugging pain caused by fluent\nmethod chaining.\n\nThe extension is in two parts. Firstly, there is a trait with two methods. `debugBreak` and `debugBreakIf`. These are \nessentially wrappers around the `xdebug_break` function installed with xdebug. \n\nUsage is like:\n\n```\nFinder::create()\n-\u003efiles()\n-\u003ename('*.php')\n-\u003edebugBreak()\n-\u003ein($configPath) \n\n```\n\nor perhaps:\n\n```\nFinder::create()\n-\u003efiles()\n-\u003ename('*.php')\n-\u003edebugBreakIf(2 === $a)\n-\u003ein($configPath) \n\n```\n\nor indeed:\n\n\n```\nFinder::create()\n-\u003efiles()\n-\u003ename('*.php')\n-\u003edebugBreakIf(function(){return app()-\u003eisRunningUnitTests();))\n-\u003ein($configPath) \n\n```\n\nTo use this, add `use CyberDuck\\Traits\\DebugsFluently` to any class where you wish to use it (or possibly its parent).\nOn my ever increasing todo list is a plan to write something that will add this to every class for you automatically.\n \nSecondly - primarily intended for usage in function chaining - are the global functions `debugBreak` and `debugBreakIf`.\n\nThe above example would become \n```\nChicken::load(meatProcess(debugBreak($sausage-\u003ebacon())-\u003eketchup()));\n```\n\nOr there is `debugBreakIf` - The second argument works in the same way as the `debugBreakIf` method in the trait.\n\n###Footnotes\n\n\u003ca name=\"myfootnote1\"\u003e1\u003c/a\u003e: There is a way in .NET - see https://davefancher.com/2016/01/28/functional-c-debugging-method-chains/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcyber-duck%2Ffluent-debug","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcyber-duck%2Ffluent-debug","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcyber-duck%2Ffluent-debug/lists"}