Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memoizing methods in frozen objects

Tags:

ruby

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.

like image 561
Drenmi Avatar asked Jul 27 '26 01:07

Drenmi


1 Answers

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
like image 163
Aleksei Matiushkin Avatar answered Jul 28 '26 19:07

Aleksei Matiushkin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!