DesignAssembler

備忘録に近い

Rubyのアクセサメソッド

ゲッターとセッター

オブジェクト指向においてカプセル化という技術があります。 これはオブジェクトの変数への、外部クラスやメソッドからの直接アクセスを遮断することです。

ただ、遮断したままだと使えないのでその変数の値を返すゲッターメソッドとその変数に値を代入するセッターメソッドを作ります。

アクセサメソッド

まず、下のコードを見てみます。

class Accessor
  def initialize(name)
    @name = name
  end
end

#参照できない
> accessor_test = Accessor.new("test")
 => #<Accessor:0x007ff80b065238 @name="test">
> accessor_test.name
NoMethodError: undefined method 'name' for #<Accessor:0x007ff80b065238 @name="test">

#instance_eval()メソッドを使えば参照可能
> accessor_test.instance_eval{@name}
 => "test"
> accessor_test.instance_eval{@name = "test2"}
 => "test2"

インスタンス変数にアクセスできません。

ゲッターとセッターを作る

ゲッターとセッターを設定すればアクセスできるようになります。

class Accessor
  def initialize(name)
    @name = name
  end
  def getName
    @name
  end
  def setName(name)
    @name = name
end

> accessor_test = Accessor.new("test")
 => #<Accessor:0x007f98ea9ae7c0 @name="test">
> accessor_test.getName
 => "test"
> accessor_test.setName("test2")
 => "test2"

ゲッターとセッターということで慣用的にgetNameとsetNameとしていますが、以下のようにしても大丈夫です。

class Accessor
  def initialize(name)
    @name = name
  end
  #ゲッター
  def name
    @name
  end
  #セッター
  def name= (name)
    @name = name
  end
end

> accessor_test = Accessor.new("test")
 => #<Accessor:0x007f98e9b239d0 @name="test">
> accessor_test.name
 => "test"
> accessor_test.name = accessor_test.name="test2"
 => "test2"
> accessor_test.name
 => "test2"

こうすればより直感的ですね。

attr_accessorメソッド

class Accessor
  def initialize(name)
    @name = name
  end
  attr_accessor :name
end

> accessor_test = Accessor.new("test")
 => #<Accessor:0x007f98e9b239d0 @name="test">
> accessor_test.name
 => "test"
> accessor_test.name = accessor_test.name="test2"
 => "test2"
> accessor_test.name
 => "test2"

アクセサメソッドメソッドを定義するメソッドで、ゲッターとセッターが自動で定義されます。

また、

  • ゲッターのみを定義したい場合はattr_readerメソッド
  • セッターのみを定義したい場合はattr_writerメソッド

を使います。

instance_eval()メソッドとattr_accessorの違い

instance_eval()は存在しないインスタンス変数名を指定してもnilが返ってきますが、attr_accessorだとNoMethodErrorが返ってきます。

また、instance_eval()はカプセル化を破壊します。

参考

d.hatena.ne.jp

qiita.com