フィヨルドブートキャンプで、オブジェクト指向プログラミングが難しいと感じている人が多いようなので、そこに至るまでの流れを正確さは度外視してざっくりお伝えします。
昔
1 # xxxまでfile読み込みの処理
2 # ...
3 # ...
4 # ...
5 # ...
6
7 goto 1 # read処理の行番号
8
9 goto 101 # write処理の行番号
10
11 goto 201 # delete処理の行番号
同じ処理を呼び出すにはそれが書いてある行へジャンプする命令を呼んでた。
関数の時代
同じ処理をまとめて名前つけて呼び出せたらいいよね。(終わったら自動で戻ってくる)
def file_read(filepath)
# ...
end
def file_write(filepath, data)
# ...
end
def file_delete(filepath)
# ...
end
filepath = "foo.txt"
text = file_read(filepath)
filepath = "bar.txt"
data = "ham egg spam"
file_write(filepath, data)
filepath = "buz.txt"
file_delete(filepath)
「めっちゃ便利!」
モジュールの時代
困ってること1
関数ってめっちゃ便利なんだけど、たくさん増えるとごちゃごちゃになるのよね。イケてるプログラマーは似ている用途の関数を一つのファイルにまとめて呼び出してるけど、みんなそうすればいいのに。
関数時代のイケてるプログラマーのプログラム。
# file.rb
def file_read(filepath)
# ...
end
def file_write(filepath, data)
# ...
end
def file_delete(filepath)
# ...
end
require "file"
filepath = "foo.txt"
text = file_read(filepath)
filepath = "bar.txt"
data = "ham egg spam"
file_write(filepath, data)
filepath = "buz.txt"
file_delete(filepath)
困ってること2
同じ用途の関数をまとめたのはいいけど、必ずセットで使う変数があるんだよね。イケてるプログラマーは変数のprefixを揃えたり、コメントに書いたりしてるけど、みんなそうすればいいのに。
関数時代のイケてるプログラマーのプログラム。
# file.rb
# file_xxx系の関数と一緒につかってネ!
file_path = ""
def file_read(file_path)
# ...
end
def file_write(file_path, data)
# ...
end
def file_delete(file_path)
# ...
end
require "file"
file_path = "foo.txt"
text = file_read(filepath)
file_path = "bar.txt"
data = "ham egg spam"
file_write(filepath, data)
file_path = "buz.txt"
file_delete(filepath)
モジュールの導入
このfile.rb
みたいなやつのことみんなモジュールって呼んでるね。モジュラーアプローチとかモジュールプログラミングと呼ぶらしい。
それがやりやすいように言語でもモジュールをサポートしよう!(Modular, Modular-2)
モジュール構文のサポート
# file.rb
Module File
name = ""
def read()
# ...
end
def write(data)
# ...
end
def delete()
# ...
end
end
require "file"
File.path = "foo.txt"
text = File.read()
File.path = "bar.txt"
data = "ham egg spam"
File.write(data)
File.path = "buz.txt"
File.delete()
同じ用途の関数が集まってるってわかるし、変数もそれらと一緒に使うってわかりやすい!嬉しい!
「めっちゃ便利!」
クラスの時代
困っていること
Fileモジュールは便利なんだけど、fileがたくさんあるときに変数の管理が大変なんだよね。
require "file"
paths = ["apple.txt", "orange.txt", "grape.txt"]
paths.each do |path|
File.path = path
puts File.read()
end
これ、それぞれのモジュール(変数)を別個のものとして持ち歩けたら便利なのになあ。
files = [File, File, File]
こういう感じにできたら似た処理をする変数と関数一式を持ち歩けて便利なのになあ。
クラス・オブジェクトの導入
クラスを雛形として書いて、newするとそれぞれ別個のものとして持ち歩けるよ!(Simula, C++)
# file
Class File
@name = ""
def initialize(name)
@name = name
end
def read()
# ...
end
def write(data)
# ...
end
def delete()
# ...
end
end
require "file"
paths = ["apple.txt", "orange.txt", "grape.txt"]
files = []
paths.each do |path|
files << File.new(path)
end
puts files # => [#<File:apple.txt>, <File:orange.txt> #<File:grape.txt>]
「めっちゃ便利!」