前提・実現したいこと
プロを目指す人のためのRuby入門という書籍を読み進めている中で、ローカル変数とインスタンス変数の挙動について理解できない箇所があり、
アクセスメソッドをいじってみたり実験をしてみたのですが、なぜこんな挙動をするのか理解ができなかったので、教えていただけると助かります。
発生している問題・エラーメッセージ
ruby
1class Product 2 attr_reader :name, :price 3 4 def initialize(name, price) 5 @name = name 6 @price = price 7 end 8 9 def to_s 10 # ここでなぜローカル変数を呼んでいるのか? 11 "name: #{name}, price: #{price}" 12 end 13end 14 15class DVD < Product 16 attr_reader :running_time 17 18 def initialize(name, price, running_time) 19 super(name, price) 20 @running_time = running_time 21 end 22end 23 24product = Product.new('A greate movie', 1000) 25p product.to_s #=> "name: A great movie, price: 1000"
コンストラクタではローカル変数をインスタンス変数にセットしているため、
コンストラクタで引数として定義されているname, priceのスコープはコンストラクタの中でのみ有効だと思っていました。
ですが、to_sメソッドではインスタンス変数を呼ぶような形でname、priceの値を呼び出すことに成功しています。(上記コードのコメントを書いている箇所です)
試したこと
私は下記の様な形でto_sメソッドではインスタンス変数を使わなければnameとpriceの値は呼び出せないと思っていました。(ローカル変数をto_sメソッドで呼ぶとエラーとなることを期待していた)
ruby
1def to_s 2 "name: #{@name}, price: #{@price}" 3end
試しにインスタンス変数で値の呼び出を行ったところ、こちらでも呼び出すことはできました。
その後、試しにアクセスメソッドを削除してみたところ、もともと期待していたエラーが返ってくるようになりました。
`to_s': undefined local variable or method `name' for #<Product:0x007fb22298a810 @name="A great movie", @price=1000> (NameError) Did you mean? @name
アクセスメソッドはインスタンス変数の「参照」「変更」を可能にするため存在するのだと思っていたのですが、ローカル変数の挙動まで変わってしまうのでしょうか?
そもそも、to_sの中で読んでいたname,priceがローカル変数ではなかったりするのでしょうか?
Rubyに関して知識が浅いので認識を間違えている箇所等あればご指摘いただけるとうれしいです。
よろしくお願いいたします。
補足情報(FW/ツールのバージョンなど)
ruby 2.4.3p205 (2017-12-14 revision 61247) [x86_64-darwin17]
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/03/03 05:35 編集
2018/03/03 21:09 編集