مرور حذف خودکار عبارات اشکالزدایی0:00
Now that our debug script is finding the calls we actually care about, we can take this one step further. Let's automatically remove these calls from the code, because we probably don't want them in there anyway. We can actually manipulate the abstract syntax tree using Nikkik's PHP parser, but if we get into the pretty printing aspect, we'll see that they actually warn you against doing this because it also reformats parts of the code which have not been modified. Now they are working on an experimental feature, but as noted, it's not yet complete. So while Nikkik's parser is awesome at parsing, it's not that great for code formatting. As I talked about earlier in the series, this is one of the reasons I recommend having a
Offset-Based Removal Approach0:42
So while Nikkik's parser is awesome at parsing, it's not that great for code formatting. As I talked about earlier in the series, this is one of the reasons I recommend having a code formatter. That way you can automatically reapply your styles after you automate any kind of code changes. But I think that's still pretty heavy, especially for a simple case where we only want to remove a very small portion of the file. What we can do instead is actually utilize this offset which we're capturing for our instances, and simply remove that portion of the file. So let's update our debug script to do just that.
Implementing substr_replace Loop1:14
instances, and simply remove that portion of the file. So let's update our debug script to do just that. Eventually we can toggle this kind of behavior with an option, but for now, let's just do it. So I'll just leave this display code in place for now, and below that we'll go ahead and remove these instances. So we can say contents is equal to substr_replace. We'll pass it contents, we're not going to replace it with anything, and now we need to pass it the offset. So that'll be the instance, the offset, and the start.
to pass it the offset. So that'll be the instance, the offset, and the start. And we also need to pass it the length. So that'll be instance, offset, end, minus the length. Alright that line got pretty massive, so let's break this up a bit. Alright that's a bit better. Now I kind of programmed with wishful thinking here, I don't have an instance, I have instances. So we're going to need to do this within a loop. So we'll say instances as instance, add our little brackets, bring this back up, and that should do everything we want.
Fixing Off-by-One Errors2:20
So we'll say instances as instance, add our little brackets, bring this back up, and that should do everything we want. And instead of writing these back to the file system, I'm just going to echo out contents for now to see if things are working. So let's go back to the command line and let's run this again. Okay, there are a couple gotchas with this approach. We're getting some stray syntax here, and that's because we have an off by one error. So we can fix that real quick by making sure that the length is the end minus start plus one. Okay, now we're just left with semicolons, and for now that's okay.
Removing Instances in Reverse2:57
one. Okay, now we're just left with semicolons, and for now that's okay. Next, as we start to scroll through this file, we'll see that files with multiple instances are getting all mangled. I remember the first time I did this, it took me a little bit to figure out why. What's happening is as we're looping over these instances, we're removing portions of the file, and as such, that's changing our offsets. A quick trick to get around that is to remove things in reverse order. That way we're always working at the bottom, and that way we know it's not affecting the offsets for the code above.
That way we're always working at the bottom, and that way we know it's not affecting the offsets for the code above. So we can fix that by simply doing array_reverse and looping over them backwards. Alright, let's try this again. Great, now we're getting the proper removals. Again, we still have some stray line breaks. This is where our code formatter is going to help. So I'll copy this code, give ourselves some room, and I'm on a Mac, so I'll pbpaste that into example.php. So if we cat out example.php, we should see that particular file with the stray semicolon.
Formatting and Writing Changes3:58
into example.php. So if we cat out example.php, we should see that particular file with the stray semicolon. So if we run our formatter, in this case fender, bin, pint, against example, we should see that it fixed everything, no blank lines, no empty statements, single blank line at the end of file, and if we cat out example.php, there we go, it cleaned all the code up for us. It's a perfect example of how all the automation that we've written builds upon itself. So with that said, let's clean this up and go ahead and do a file_put_contents, for our changes. Now before I run all that, let's go ahead and add, oops, I actually don't want that
Pre-commit Hook Automation4:39
our changes. Now before I run all that, let's go ahead and add, oops, I actually don't want that example, let's go ahead and remove that example.php, git add ., git commit -m "new script to remove debug calls." Awesome. And hey, look, our var_dump is still in there. So let's update our git commit hook to go ahead and run our new debug calls. So let's get into git/hooks/pre-commit, and we'll copy this line and make sure we run our script, debugCalls, debugCalls, and this time we'll pass it just the files that were modified.
run our script, debug calls, debug calls, and this time we'll pass it just the files that were modified. Now I don't have any changes, so when you're adding automation to your project for the first time, you're probably going to have to run these things manually. So let's go ahead and run our scripts, debug calls, and we should see that we have changes for all these files. So if we just look through them quickly with git add -p, we can see that it removed the print_r there, it removed our var_dump, our var_export, our dd statements, everything that we expected. But of course that semicolon is still left in there.
Handling Edge Case Syntax5:56
that we expected. But of course that semicolon is still left in there. So let's see when we commit this, remove debug calls, that it cleans everything up and makes the commit. Uh oh, that's a little unexpected. Do we actually have a syntax error? Let's go take a look at this All.php file and see what's happening. Ooh, looks like we got something removed on line 10. Why was that? I'm going to go ahead and revert this line and see what happened.
Why was that? I'm going to go ahead and revert this line and see what happened. That's a pretty interesting boundary case. This is actually an instance we should remove, but it's part of a larger statement that actually can't simply have that code removed. Now you can make the argument that this is pretty odd code and it's probably okay if this was in the project and ended up throwing an error because it's alerting me to something I probably didn't mean to do in the first place. But again, even when using a parser, there's always going to be some edge cases. With the infinite way you can write code using a dynamic language like php.
But again, even when using a parser, there's always going to be some edge cases. With the infinite way you can write code using a dynamic language like php. So I'll put this back to true, which is what it was in the beginning. Let's add that change and let's try to run our commit again. Great. And if we go back to our code, we'll see that upon committing, it ran Pint, which formatted everything and removed those semicolon artifacts.
