今回はrubyのインスタンス変数とクラス間での引き渡しについて。
今もよく躓くところだが、理解できた部分をアウトプットしていく!
initialize
メソッドとインスタンス変数に関して
class Item
attr_accessor :name, :price
def initialize(name, price)
@name = name
@price = price
end
def display
puts "#{@name}の値段は#{@price}です"
end
end
item01 = Item.new("バナナ", 150)
item01.display
上記コード、item01.display
の実行結果「バナナの値段は150です
」が出力されるまで。
ここではinitialize
メソッドとインスタンス変数に関して。
item01 = Item.new("バナナ", 150)
ここでItemクラスをインスタンス化して、その際に引数として「バナナ」と「150」を渡す。
インスタンス化と同時にinitialize
メソッドが実行され。引数(name, price)=「バナナ」と「150」を受け取る。
そのあとに@name
,@price
にそれらの値を代入している動作。
これによりインスタンス変数@name
,@price
が出来上がるので、クラス内での呼び出しが可能となる。
item01.display
メソッドにて、
puts "#{@name}の値段は#{@price}です"
のように、インスタンス変数を値として呼び出し、
実行結果のバナナの値段は150です
が出力される。
Itemクラスで使用しているattr_accessor :name, :price
に関して
このattr_accessor
、またはattr_reader
、attr_writer
は、
本当にざっくり言うと、accessorは読み書き可能。readerは読み取りのみ。writerは書き込みのみ。
クラス間での変数=値の受け渡しには重要なメソッドになるので、後述していく。
クラス間でのインスタンス変数の呼び出しについて
class Customer
def initialize(item)
@item = item
end
def item_display
puts "#{@item.name}の値段は#{@item.price}です"
end
end
customer = Customer.new(item01)
customer.item_display
上記のコードを使って、
Itemクラスからのインスタンス変数@name,@price
を引き継いで出力させるまで。
(最終的な出力はItemクラスで出力したバナナの値段は150です
と同じ)
Customer.new(item01)
により、
Itemクラスのインスタンスである「バナナ=@name」と「150=@price」がCustomerクラスに引数として渡される。
その後、Customerクラスのinitialize(item)
が実行され、
渡された「バナナ=@name」と「150=@150」が@item
の中に格納される。
(binding.irbで@item
を確認すると、「#<Item:0x00007fa7d0c42eb0 @name="バナナ", @price=150>
)
これによって、 インスタンス変数@itemが出来上がるので、クラス内のメソッド「item_display」で中の値を呼び出すことができる。
puts "#{@item.name}の値段は#{@item.price}です"
=バナナの値段は150です
先ほどattr_accessor
メソッドについて、読み書き可能。という形で記述した。
今回Itemクラスの変数をCustomerクラスに引き渡したが、
これがItemクラスにaccessorメソッドが無かった場合。
[undefined method `name' for an instance of Item (NoMethodError)
]
=Customerクラスをインスタンス化する際に、
Itemクラスのインスタンスであるものを呼び出したいが、
アクセサが無いのでエラーが返ってくる。(attr_reader
であれば読み取り可能となるので、今回のコードであればreaderだけでもokとなる)
以下は雑談。
クラスの中にメソッドを入れてクラスごとに独立化させ、
外から呼び出しするという構図の理解が難しい!!
且つ、クラス間での値の受け渡しなどになると、インスタンス化する際に何を渡せばいいのか、という点で混乱してしまう。
毎日一歩ずつ、少しでも前進できればと願う毎日!!