Debugging collections
Lately I've been working a lot with collections in Laravel. If you're not in the know: a collection is a sort of super charged array with a lot of powerful functions to transform the data inside it. The only thing I found a bit of a hassle is how to debug the various steps in a collection chain. Here's how I improved the workflow.
Using a collection class you can build up a chain of functions to transform data. Take a look at this example (I left out the function bodies to make it a bit shorter).
collect($items)
->filter(function() {
...
})
->unique(function() {
...
})
->map(function() {
...
})
->sortBy(function() {
...
});
Image you are debugging this code. You want to see what the values are after the map
function. To do that you could wrap the code starting from the collection call until right after the map
function in a dd
function.
dd(collect($items)
->filter(function() {
...
})
->unique(function() {
...
})
->map(function() {
...
}))
->sortBy(function() {
...
});
Sure enough, the contents of the collection after the map
function will get dumped to the screen. But there's some work involved: you have to insert code a the beginning of the collection and an extra closing parenthesis after the map
function. To my eyes this isn't very readable. It's also a bit of a hassle to remove the dd
statement, that closing parenthesis is easily forgotten. I'm exaggerating the problems a bit, but I can assure you'll get tired of debugging like this really quick. There must be a better way.
Laravel's collection class is Macroable
. That means we can add functions to the class at runtime. To improve our debugging workflow let's create a simple dd
macro:
Collection::macro('dd', function () {
dd($this);
});
To use the macro anywhere in a project you could place it a ServiceProvider
. Take a look Blender, our Laravel template, for an example.
Using the macro debugging a collection becomes much simpler. Here's how to use it:
collect($items)
->filter(function() {
...
})
->unique(function() {
...
})
->map(function() {
...
})
->dd()
->sortBy(function() {
...
});
To see the values after a particular step in the chain you simply have to add one line of code. It's perfectly readable. After you've done your debugging there's only one line to remove. Using PHPStorm's alt
+shift
+arrow-up
and alt
+shift
+arrow-down
shortcuts the ->dd()
line can be easily moved to the previous or next part of the collection chain.
You can learn more about collections in Laravel's official documentation and Adam Wathan's excellent book on the subject.
Can this technique be adapted for other IDEs besides PHPStorm? slope game asks.