I'm working with an abstract syntax tree, where each vertex is a subclass of a Node class. This base class is defined in a third party library, and the Node objects are frozen upon construction.
Now I'm performing some expensive operations that traverse the tree, sometimes recursively, and would like to memoize the result of those. Below is an example of such a subclass, and operation result being memoized using the "classic" Ruby pattern:
class DefNode < Node
def visibility_scope
@visibility_scope ||= VisibilityScopeResolver.new(self).resolve
end
end
However, since the Node constructor freezes the object, trying to assign to an instance variable results in an error:
DefNode.new(children).visibility_scope
#=> RuntimeError: can't modify frozen DefNode
Is there a way to (idiomatially) perform memoization in frozen objects? Ideally without overriding the constructor in each subclass.
I am not sure about “idiomatic,” but when I have been there, I used a hash on the class itself:
class DefNode < Node
def self.visibility_scopes
@visibility_scopes ||= {}
end
def visibility_scope
self.class.visibility_scopes[__id__] ||=
VisibilityScopeResolver.new(self).resolve
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With