よくわかってないattr_accessorに関して学んだことのメモ。
※本記事は更新中で変更の可能性があります
※2020/5/14時点
以下、今回のサンプルコードです。
※attr_accessorはコメントにしてます
class User
# attr_accessor :name
# setter: name=(value)
# getter: name
def initialize(name)
@name=name
end
def sayhi
puts "hi.#{@name}"
end
end
user=User.new("bob")
user.sayhi
まず、自分で定義するインスタンス変数(@name)に関しては外部からアクセスすることはできない。
ここでいう外部と内部ですが、アクセスできる範囲としては
サンプルコードでいうと、
class User
# attr_accessor :name
# setter: name=(value)
# getter: name
def initialize(name)
@name=name
end
def sayhi
puts "hi.#{@name}"
end
end
ということになるかと思います。
そして、newでインスタンスを作成し、sayhiメソッドを呼び出した場合、
sayhiメソッドが直接、インスタンス変数をみにいくのでattr_accessor :nameはコメントアウトのママでもOK。
上記サンプルコードをコンソールで吐き出すと
ec2-user:~/environment/ruby_lessons $ ruby hello.rb
hi.bob
となる。
続いてサンプルコードに、「外部」からインスタンス変数にアクセスしようとするコードを追記。
class User
# attr_accessor :name
# setter: name=(value)
# getter: name
def initialize(name)
@name=name
end
def sayhi
puts "hi.#{@name}"
end
end
user=User.new("bob")
user.sayhi
# 追記箇所(attr_accessorメソッドはコメントのママ)
user.name ="bob.jr"
p user.name
これをコンソールで吐き出すと、、、
ec2-user:~/environment/ruby_lessons $ ruby hello.rb
hi.bob
Traceback (most recent call last):
hello.rb:89:in `<main>': undefined method `name=' for #<User:0x0000000002973f40 @name="bob"> (NoMethodError)
エラーがでます。
これは外部から直接、nameにアクセスしようとしているからです(先ほどのメソッド経由とは異なります)
なので、これができるようにするには、セッターゲッターを含む
attr_accessorメソッドのコメントをとり、有効にしてあげると、、、
class User
attr_accessor :name
# setter: name=(value)
# getter: name
def initialize(name)
@name=name
end
def sayhi
puts "hi.#{@name}"
end
end
user=User.new("bob")
user.sayhi
# 追記箇所(attr_accessorメソッドはコメントをはずす)
user.name ="bob.jr"
p user.name
こうなり、コンソールで吐き出すと
ec2-user:~/environment/ruby_lessons $ ruby hello.rb
hi.bob
"bob.jr"
見事に書き換え&表示に成功。
念のため、書き換え前の出力も追加してみる。
class User
attr_accessor :name
# setter: name=(value)
# getter: name
def initialize(name)
@name=name
end
def sayhi
puts "hi.#{@name}"
end
end
user=User.new("bob")
user.sayhi
# 追記箇所
p user.name
user.name ="bob.jr"
p user.name
すると
ec2-user:~/environment/ruby_lessons $ ruby hello.rb
hi.bob
"bob"
"bob.jr"
いい感じ。
上書きされた状態でメソッドを呼び出すコードを追加。
class User
attr_accessor :name
# setter: name=(value)
# getter: name
def initialize(name)
@name=name
end
def sayhi
puts "hi.#{@name}"
end
end
user=User.new("bob")
user.sayhi
p user.name
user.name ="bob.jr"
p user.name
# 追加部分
user.sayhi
すると
ec2-user:~/environment/ruby_lessons $ ruby hello.rb
hi.bob
"bob"
"bob.jr"
hi.bob.jr
上書きされた形でメソッドを呼び出せた!
こんな感じで「外部」からインスタンス変数の値にアクセスしたい場合に
attr_accessorメソッドを用いるとよい、らしい。