I learned from the author that you can use ObjectSpace.dump_shapes to introspect on these. I don’t know a lot about Ruby internals, but if it’s possible to tie these back to classes at the end of (say) a test suite run, classes with lots of shapes would be compelling candidates for this optimization.
On the other hand, I love Ruby’s @foo ||= expensive_call() idiom and the garbage collector can fight me for it.
If you know that expensive_call will never return nil or false, you should definitely do this. Just make sure to initialize the instance variable to nil in initialize.
Do you have any automated tools or patterns for catching regressions related to object shapes? I could imagine possibly running this on CI and then diffing between runs. Maybe a linter that errors on an instance variable used without being defined in the constructor (for example).
I learned from the author that you can use ObjectSpace.dump_shapes to introspect on these. I don’t know a lot about Ruby internals, but if it’s possible to tie these back to classes at the end of (say) a test suite run, classes with lots of shapes would be compelling candidates for this optimization.
On the other hand, I love Ruby’s
@foo ||= expensive_call()idiom and the garbage collector can fight me for it.If you know that
expensive_callwill never return nil or false, you should definitely do this. Just make sure to initialize the instance variable tonilin initialize.Do you have any automated tools or patterns for catching regressions related to object shapes? I could imagine possibly running this on CI and then diffing between runs. Maybe a linter that errors on an instance variable used without being defined in the constructor (for example).
Why not
nilinstead ofNULL = Object.new? Is this to catch cases wherenilis a valid value?Ya, this is for the case when you try to memoize something that could possibly return a “falsey” value.
For example:
Is there a benchmark somewhere about the difference between using/not using object shapes? Are we saving RAM, using less CPU, both?