Ruby クロージャを使ってインスタンス変数を減らす
インスタンス変数は悪である。
だって、クラス内のどこからでも、値を改変できるから。
そこで、インスタンス変数を減らす手立を考えてみた。
以下、ゲッターもどき。
構造体を返す。構造体はラムダをgetメンバに持っている。
ラムダはクロージャになる。変数immutable_varは保持される。
変数の中身(yield)は、後ほどブロックで渡す。
def make_getter immutable_var = yield struct = Struct.new(:get) struct.new( -> { immutable_var } ) end
以下、ゲッター兼セッターもどき。
getメンバ、setメンバを持つ。もちろんクロージャ。
def make_accessor immutable_var = yield struct = Struct.new(:get, :set) struct.new( -> { immutable_var }, -> new_var { immutable_var = new_var } ) end
以下で変数の中身を定義する。
'白石麻衣'、'平手友梨奈'となっているブロックの中身は、がっつり処理を書いてよい。
それら変数をまとめて、こちらも構造体で返す。
def make_immutables struct = Struct.new(:nogi, :keyaki) struct.new( make_getter { '白石麻衣' }, make_accessor { '平手友梨奈' }, ) end
コンストラクタで、上記構造体をインスタンス変数に入れる。インスタンス変数を使ってしまうが、これはしょうがないと思う。
def initialize @immutables = make_immutables end
変数を呼び出す。
呼び出し方が冗長な気もするが、憎きインスタンス変数を減らせたので、良しとする。
def execute p @immutables.nogi.get.call # 白石麻衣 p @immutables.keyaki.get.call # 平手友梨奈 @immutables.keyaki.set.call('長濱ねる') # 長濱ねるをセット p @immutables.keyaki.get.call #長濱ねる end
うーん、他に良い方法あるのかなぁ…。