基本的すぎる内容ですが、インスタンス変数を使わないことでコードが冗長化していることがあったので、戒めとして書きます。自分用の学習メモです。
インスタンス変数が活用できていない...
require "time"
require 'csv'
class User
attr_reader :name, :birthday
def initialize(name:, birthday:)
@name = name
@birthday = birthday
end
def self.calc_age(now, birthday)
((now - birthday) / 365).to_i
end
end
class Product
attr_reader :name, :quantity, :price
def initialize(name:, quantity:, price:)
@name = name
@quantity = quantity
@price = price
end
end
CSV.foreach("sales.csv", headers: true) do |row|
user = User.new(name: row[0], birthday: row[1])
now = Time.now
birthday = Time.parse(user.birthday)
age = User.calc_age(now, birthday)
product = Product.new(name: row[2], quantity: row[3].to_i, price: row[4].to_i)
puts "#{user.name}(#{age})は#{product.name}を#{ product.quantity * product.price}円お買い上げ。"
end
sales.csv
名前,誕生日,買上品目,数量,単価
つんく♂,1968/10/29,チロルチョコ,13,10
はたけ,1968/8/17,雪見だいふく,3,100
まこと,1968/12/31,チョコモナカ,3,140
たいせい,1969/11/29,フルーツコッペ,4,300
改善点
-
変数nowを定義する必要はない
-
birthdayはプロパティとして持っているのでそのままインスタンス変数で使えば良い
-
quantityとpriceはプロパティとして持っているのでそのままインスタンス変数で使えば良い
- 今回はさらに簡潔にするためにメソッドに切り出す
-
その他
- 年齢算出処理ではインスタンスに含まれるデータを参照しているのでクラスメソッドではなくインスタンスメソッドで定義する
インスタンス変数を活用する
require "time"
require 'date'
require 'csv'
class User
attr_reader :name, :birthday
def initialize(name:, birthday:)
@name = name
@birthday = birthday
end
def age
((Date.today - @birthday) / 365).to_i
end
end
class Product
attr_reader :name, :quantity, :price
def initialize(name:, quantity:, price:)
@name = name
@quantity = quantity
@price = price
end
def sum
@quantity * @price
end
end
CSV.foreach("sales.csv", headers: true) do |row|
user = User.new(name: row[0], birthday: Date.parse(row[1]))
product = Product.new(name: row[2], quantity: row[3].to_i, price: row[4].to_i)
puts "#{user.name}(#{user.age})は#{product.name}を#{product.sum}円お買い上げ。"
end
プロパティとして持っているものはインスタンス変数でコードが簡略化できないか疑うこと。
当たり前のことでも実際にコードを書くとできていなかったりするので、適宜メモを残していこうと思います。