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"
アクセサメソッドはメソッドを定義するメソッドで、ゲッターとセッターが自動で定義されます。
また、
を使います。
instance_eval()メソッドとattr_accessorの違い
instance_eval()は存在しないインスタンス変数名を指定してもnilが返ってきますが、attr_accessorだとNoMethodErrorが返ってきます。
また、instance_eval()はカプセル化を破壊します。