Summary
Currently running po
in lldb on a Swift object will print all stored properties. I've come across a few cases where I have a very large model object, with 10s of stored and computed properties. It would be great if there was some option for po
or separate command which will print the computed properties also.
Example
Reference the following code for this example. Note that this is a very simple object, and this pitch will mainly benefit large complicated objects.
struct ShoppingBag {
var apples: Int
var bananas: Int
var fruits: Int { return apples + bananas }
}
let bag = ShoppingBag(apples: 3, bananas: 3)
Running (lldb) po bag
returns the following:
▿ ShoppingBag
- apples : 3
- bananas : 3
I'd like some sort of way to have the following printed:
▿ ShoppingBag
- apples : 3
- bananas : 3
- fruits : 6
Workarounds
There are a few workarounds, the most obvious being just run (lldb) po bag.fruits
. Another would be to provide a data formatter for ShoppingBag
. One interesting one is to have ShoppingBag
conform to CustomReflectable
, as follows:
extension ShoppingBag: CustomReflectable {
var customMirror: Mirror {
return Mirror(self, children: ["apples": apples, "bananans": bananas, "fruits": fruits], displayStyle: .struct)
}
}
Then, running (lldb) po bag
will return:
(lldb) po bag
▿ ShoppingBag
- apples : 3
- bananans : 3
- fruits : 6
The main problem with this solution is the implementation of var customMirror: Mirror
is pretty messy, even with a simple object like ShoppingBag
. The main benefit this pitch would have is for complex objects with many properties, where it would be fairly time consuming & messy to implement var customMirror: Mirror
. If the compiler were able to automatically implement this property when CustomReflectable
is conformed to, this would solve that issue.
Issues
There are a couple issues with including this behavior by default for po
- A computed property can mutate the object (this isn't typical but possible).
(lldb) po
should generally not mutate any memory. - A computed property may be expensive to compute. Again, this is atypical but still possible.
This could be solved in a few ways, either by adding a flag to lldb to opt in or out of this functionality, or adding a flag to class
/struct
definitions that tell the expression parser to skip computed properties (or even specific computed properties) when po
ing the object.
Conclusion
Let me know what your thoughts are/if you have any enhancements to the pitch. Thanks,
Greg