クラスを使わないプログラミング
(例)
# ユーザのデータを作成する
users = []
users << { first_name: 'Hanako', last_name: 'Yamada', age: 8 }
users << { first_name: 'Taro', last_name: 'Yamamoto', age: 10 }
# 氏名を作成するメソッド
def full_name(user)
"#{user[:first_name]} #{user[:last_name]}"
end
# ユーザのデータを表示する
users.each do |user|
puts "氏名: #{full_name(user)}, 年齢: #{user[:age]}"
end
問題点
- ハッシュを使用すると、キーをタイプミスした場合、エラーは表示されず、nilが返ってくる。そのため、不具合に気づかない可能性がある点
- ハッシュは新しくキーを追加したり、内容を変更できるため、「脆くて壊れやすいプログラム」になりがちな点
(例1)
users[0][:first_name] #=> "Hanako"
users[0][:first_mame] #=> nil
(例2)
# 勝手に新しいキーを追加
users[0][:food] = 'rice'
# 勝手にfirst_nameを変更
users[0][:first_name] = 'dozaemon'
puts users[0]
#=> {:first_name=>"dozaemon", :last_name=>"Yamada", :age=>8, :food=>"rice"}
クラスを使ったプログラミング
(例)
# Userクラスを定義する
class User
attr_reader :first_name, :last_name, :age
def initialize(first_name, last_name, age)
@first_name = first_name
@last_name = last_name
@age = age
end
end
# ユーザのデータを作成する
users = []
users << User.new('Hanako', 'Yamada', 8)
users << User.new('Taro', 'Yamamoto', 10)
# users[0].first_name
# 氏名を作成するメソッド
def full_name(user)
"#{user.first_name} #{user.last_name}"
end
# ユーザのデータを表示する
users.each do |user|
puts "氏名: #{full_name(user)}, 年齢: #{user.age}"
end
#=> 氏名: Hanako Yamada, 年齢: 8
# 氏名: Taro Yamamoto, 年齢: 10
Userクラスを導入すると、タイプミスした時にエラーが発生します。
(例)
puts users[0].first_name #=> 'Hanako'
puts users[0].first_mame #=> undefined method `first_mame' for #<User:0x00007f888d08c150> (NoMethodError)
新しく属性を追加したり、内容を変更したりすることも防止できます。
(例)
# 勝手に属性を追加できない
users[0].food = 'rice' #=> undefined method `food=' for #<User:0x00007fefae1300d8> (NoMethodError)
# 勝手にfirst_nameを変更できない
users[0].first_name = 'tanjiro' #=> undefined method `first_name=' for #<User:0x00007faa210c0418> (NoMethodError)
また、クラスの内部にメソッドを追加することもできます。
(例)full_nameメソッドをUserクラスの内部で定義する
# Userクラスを定義する
class User
attr_reader :first_name, :last_name, :age
def initialize(first_name, last_name, age)
@first_name = first_name
@last_name = last_name
@age = age
end
# 氏名を作成するメソッド
def full_name
"#{first_name} #{last_name}"
end
end
# ユーザのデータを作成する
users = []
users << User.new('Hanako', 'Yamada', 8)
users << User.new('Taro', 'Yamamoto', 10)
# ユーザのデータを表示する
users.each do |user|
puts "氏名: #{user.full_name}, 年齢: #{user.age}"
end
#=> 氏名: Hanako Yamada, 年齢: 8
# 氏名: Taro Yamamoto, 年齢: 10
このように、クラスは内部にデータを保持し、さらに自分が保持しているデータを利用する独自のメソッドを持つことができます。データとそのデータに関するメソッドが常にセットになるため、クラスを使わない場合に比べてデータとメソッドの整理がしやすくなります。