1. 11
    1. 3

      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.

      1. 3

        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.

        1. 1

          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).

      2. 2

        Why not nil instead of NULL = Object.new? Is this to catch cases where nil is a valid value?

        1. 3

          Ya, this is for the case when you try to memoize something that could possibly return a “falsey” value.

          For example:

          def memo
            @memo ||= slow
          end
          
          def slow
            sleep 123
            nil
          end
          
        2. 1

          Is there a benchmark somewhere about the difference between using/not using object shapes? Are we saving RAM, using less CPU, both?