孤独プログラマー譚

孤独死が近い。

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


うーん、他に良い方法あるのかなぁ…。