【一人 Ruby Advent Calendar 2017】外部からインスタンス変数にアクセスする【11日目】
一人 Ruby Advent Calendar 2017 11日目の記事になります。
今回も昨日に引き続いて外部からクラスの内部へアクセスするネタです。
インスタンス変数
さて、Ruby では @value
というような『@
+ 名前』の変数を使用することで『そのオブジェクト内で共通して使用できる』インスタンス変数を定義することができます。
class X def initialize n @value = n end def to_s @value.to_s end end puts X.new 42
このようなインスタンス変数は通常は外部からは参照できず、インスタンス変数を書き換えたり取得したい場合は .attr_accessor
などを使ってアクセッサメソッドを定義するのが一般的です。
class X # @value というインスタンスう変数に対する # X#value # X#value= # アクセッサメソッドを定義する attr_accessor :value def get @value end end x = X.new # @value に対して書き換えたり x.value = 42 # @value を取得したりする p x.value # => 42 p x.get # => 42
このようにして .attr_accessor
を利用することで @value
のアクセッサを簡単に定義することができます。
インスタンス変数を外部から直接参照する
さて、先程は .attr_accessor
でアクセッサメソッドを定義することで外部からアクセスするようにしましたが、次は直接アクセスしてみましょう。
#instance_exec
や #instance_eval
を使う
みんな大好き #instance_exec
を使用することで簡単にアクセスできます。
class X def initialize @value = -5 end def get @value end end x = X.new # instance_exec のブロック内で変数を参照したり p x.instance_exec { @value } # => -5 # 変数を書き換えたりする x.instance_exec { @value = 42 } p x.get # => 42
#instance_exec
を使えば Ruby でやりたい放題ですね。
#instance_variable_set
と #instance_variable_get
を使う
#instance_variable_set
と #instance_variable_get
を利用することができます。
これらのメソッドはその名の通り『直接インスタンス変数を参照する為』のメソッドです。
class X def initialize @value = -5 end def get @value end end x = X.new # 任意の名前のインスタンス変数を取得する # @ を付けることに注意 p x.instance_variable_get(:@value) # => -5 # 変数を書き換えたりする x.instance_variable_set(:@value, 42) p x.get # => 42
このようにわざわざ #instance_exec
などを利用せずにインスタンス変数にアクセスするための専用のメソッドが用意されています。