2017-07-15 2 views
2

私は、各頂点がNodeクラスのサブクラスである抽象構文ツリーを使って作業しています。この基本クラスは第三者のライブラリで定義されており、Nodeオブジェクトは構築時にフリーズされます。フリーズされたオブジェクトのメソッドをメモにする

今、私はツリーを横切る高価な操作を実行しています。時には再帰的に操作し、その結果をメモしたいと思います。 Nodeコンストラクタがエラーでインスタンス変数結果に代入しようと、オブジェクトをフリーズするので、

class DefNode < Node 
    def visibility_scope 
    @visibility_scope ||= VisibilityScopeResolver.new(self).resolve 
    end 
end 

しかし:以下、このようなサブクラス、及び演算結果の一例は、「古典的な」Rubyのパターンを使用してメモ化されています:

DefNode.new(children).visibility_scope 
#=> RuntimeError: can't modify frozen DefNode 

フリーズしたオブジェクトでメモを行う方法はありますか?理想的には、各サブクラスのコンストラクタをオーバーライドしないでください。

答えて

0

私は何をやってしまったことは、条件付きで可能にprivateライターを、宣言していますそれはおよそ理由にわずかに容易である、状態はインスタンス自体に含まれていることを可能にする、いかなる不測のを持っていないので

class DefNode < Node 
    def visibility_scope 
    resolved_visibility_scope ||= VisibilityScopeResolver.new(self).resolve 
    end 

    private 

    attr_writer :resolved_visibility_scope 
end 

私はこのソリューションで行きました。でも、凍結対象に、値を設定します副作用。これの1つの欠点は、一見すると、おなじみの "バラのメモ"パターンのようには見えないということです。

作者は#visibility_scope=と定義されているだけなので、visibility_scopeという名前でもかまいません。したがって、手動で定義されたリーダーと競合しません。私は、混乱の可能性を最小限に抑えるために、別の名前を付けることを決めました。

1

私は「慣用的な」わからないですが、私はそこにされているとき、私はクラス自体にハッシュを使用:

class DefNode < Node 
    def self.visibility_scopes 
    @visibility_scopes ||= {} 
    end 

    def visibility_scope 
    self.class.visibility_scopes[__id__] ||= 
     VisibilityScopeResolver.new(self).resolve 
    end 
end 
関連する問題