インスタンス変数に、内部から getter でアクセスするのは割とよくやる手法です

なんか表題が偉そうだ(笑

こちら からトラバが来ていたので取り急ぎ。

ポイントは以下の二つ

なので、options はインスタンスメソッドだと思います。なぜ Capistrano でそうしているかはコード見ていないので判りませんが、単に読みやすくなる(ケースがある)のと getter/writer が単にインスタンス変数を返しているわけではない場合などは、そうします*1

ただこの方法には副作用があるのは有名な話です。メソッド名とローカル変数の見た目の区別がつかないため、ちょっと特殊な動作をします。

先ずは getter から。以下のようなメソッド群があるとします。

def some_getter
  puts "some_getter called"
end

def getter_access
  some_getter
end

def no_getter_access
  some_getter = "local variable"
  some_getter
end

some_getter が getter じゃないのは気にしないでください(

で、 getter_access と no_getter_access は名前の通りの動作をします。

irb* getter_access
some_getter called
=> nil
irb> no_getter_access
=> "local variable"

同名のローカル変数に対する代入式があると、同一スコープ内でそれをローカル変数とみなします。

となると setter がレシーバ抜いた形で呼びだせないんじゃないかというと、その通りです。self などを明示的に指定する必要があります。

def some_writer=(val)
  puts val
  puts "some_writer called."
end

def non_writer_access
  some_writer = "some_writer"
end

def writer_access
  self.some_writer = "somevalue"
end

実行結果:

irb> no_writer_access
=> "some_writer"
irb> writer_access
somevalue
some_writer called.
=> "somevalue"

自分はと言えば、可能な限り直接インスタンス変数を参照することはしなくなっています。インスタンス変数の挙動というか、アクセス方法の一貫性を保つには getter/writer にするのが望ましいと思っています。値の扱い方をを変えたい場合など、getter/writer を修正すればそれで済むので。

でも、間違えないように self を明示することが多い気がしますw

*1:その場合、厳密な意味で getter/writer って言うのかは判りませんがw