疑問 インスタン変数は@をつけるのかつけないのか。
railsのフレームワークを導入しコントローラ内で
contoroller
1index 2 @item = Item.all 3end
の@itemの様にインスタンス変数は変数の前に@マークをつけると認識していました。
しかし復習としてプロゲートをやり直すと
class Menu # nameとpriceというインスタンス変数を用意してください attr_accessor :name attr_accessor :price end
の様に:name、:priceの前には@がついていません。
@は着く場合ととつかない場合があるのでしょうか。
ご教示いただきたいです。
よろしくお願いいたします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
ベストアンサー
まずはこれを抑えてください
attr_accessor
が何をしているかというと、
- 外部からの値の参照を可能にしている
- 外部からの値の設定を可能にしている
rb
1class Hoge 2 attr_accessor :name 3end 4 5x = Hoge.new 6x.name = 'hoge' # 外部から値の設定が可能
下記はエラーになる
rb
1class Hoge 2 def initialize(name) 3 @name = name 4 end 5end 6 7hoge = Hoge.new 8hoge.name = 'tee' # 外部からのアクセス不可なのでエラー 9 10## attr_accessor :nameをつけると外部からの設定と参照が可能になる
ここから本題
インスタンス変数を用意するということは、値を入れる箱を用意
すると同義である
rb
1# 下記の状態ですでにname属性(インスタンス変数)にアクセスできる 2# 箱は完成していると言って良い 3class Hoge 4 attr_accessor :name 5end 6 7x = Hoge.new 8p x.name # nill 値を何も設定していないため 9x.name = 'hoge' # nameに外部から値を設定できる
attr_accessor
を使って値の設定や参照が可能なら@は必要ないのではないか?
この疑問は最もですが、そうはいきません。インスタンス生成時に値を設定するには@が必要です。
rb
1class Hoge 2 def initialize(name) 3 @name = name 4 end 5end 6 7x = Hoge.new('hoge') # 初期化時に値を設定できる
これは大きなメリットです。
例えば属性(インスタンス変数が) 4つある場合
rb
1# @を使わない場合 2x = Hoge.new 3x.name = 'tee' 4x.age = 18 5x.tall = 175 6x.hobby = 'running'
rb
1# @を使う場合 2x = Hoge.new('tee', 18, 175, 'running')
両者の運用方法は
このようにどちら使っても開発を進めることは可能ですが、使い勝手に差があります
下記のように併用する運用が一番堅実な使い方でしょう
- インスタンス変数には@をつける
- 外部からアクセスしたい場合にはattr_accessorを併用する
rb
1# nameは外部からのアクセスが可能 2# 初期化時に一度に属性の中身を設定可能 3class Person 4 attr_accessor :name 5 6 def initialize(name, age) 7 @name = name 8 @age = age 9 end 10 11end
@
を推奨する理由は、初期化時に値を設定できるからですが、他にも理由があります。
attr_accessor
は外部からの参照や設定ができるので、セキュリティ的に好ましくありません。
不要な場面で呼び出してしまう可能性もありバグにつながります。@
を使えば外から直接読み書きされる心配がないのでセキュリティ上のメリットが多いです。
基本は@
使用して初期化時に値を設定できるようにし、必要なものだけattr_accessor
の併用で外部に露出させましょう
余談
attr_accessor
の仕組みですが、自動でgetter
メソッドとsetter
メソッドを定義しているだけです。
attr_accessor
を使わなくても手動でgetter
メソッドとsetter
メソッドをclass内に定義すれば、
attr_accessor
が適応されているのと同じ状態にすることが可能です。
また、読み取り専用や書き取り専用のattr_accessor
の親戚もいます。
興味があれば調べてみてください。
投稿2022/07/09 16:45
編集2022/07/09 16:56総合スコア191
0
:name
はインスタンス変数ではありません。シンボルのリテラルです。
attr_accessor
というメソッドは、引数に:name
というシンボルを与えることで、
Ruby
1def name 2 @name 3end 4def name=(val) 5 @name = val 6end
という2つのメソッドが自動的に定義するという機能を持っています。
インスタンス変数@name
に代入したり参照したりすることと、そのインスタンス変数を扱う2つのメソッドを定義することは、関連はしていますが、概念としては別物です。
「インスタンス変数を用意」という日本語も意味が微妙ですね。具体的に何を言ってるのか。
Ruby
1class Menu 2 # nameとpriceというインスタンス変数を用意してください 3 attr_accessor :name 4 attr_accessor :price 5end
がテキストにそのまま書いてあったのなら、「インスタンス変数を用意」=「インスタンス変数を扱う2つのメソッドを定義」という意味で使っているのかもしれませんが、一般的ではない気がします。
投稿2022/07/09 08:44
総合スコア84559
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
:name、:priceの前には@がついていません。
が、attr_accessor :name
は@name
というインスタンス変数をもとにして動きます。
投稿2022/07/09 08:07
総合スコア145184
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。