Tbpgr Blog

Ruby プログラマ tbpgr(てぃーびー) のブログ

Ruby | Performing Work | メソッドの作成手順(レガシーや標準ライブラリの制約あり)

概要

メソッドの作成手順(レガシーや標準ライブラリの制約あり)

前提

Confident Rubyではメソッド内の処理を次のように分類しています。
・Collecting Inputs(引数チェック、変換など)
・Performing Work(主処理)
・Delivering Results(戻り値に関わる処理)
・Handling Failure(例外処理)

当記事は上記のうち、Performing Work(主処理)に関する話です。

手順

・メッセージの識別
・ロールの識別
・システム内のオブジェクトとわれらが判別したロールのギャップを埋める

サンプル仕様

Rubyソースコードから単一行コメントを抽出して
「TODO:」コメントは todos.txt に
その他のコメントは others.txt に
出力する。

必要な処理を抽出

・ファイル名をもとにファイルのソースコードを読み取る
・単一行コメントでTODO: を含む行を抽出し、TODOコメントリストを返却する
・単一行コメントでTODO: を含まない行があれば、TODOコメントリストを返却する
・TODOコメントリストを todos.txt に出力する
・OTHERコメントリストを others.txt に出力する

メッセージの識別

・#read_source_code
・#find_todos
・#find_others
・#write_todos
・#write_others

ロールの識別

ruby_source_code_file
ruby_source_code
・todos_comment_file
・others_comment_file

レシーバーの識別

ruby_source_code_file.read_source_code
ruby_source_code.find_todo_comments
ruby_source_code.find_other_comments
・todo_comment_file.write_todos
・other_comment_file.write_others

コードにする

標準ライブラリの部分とドメイン言語の部分が混在して
抽象度がバラバラです。

def output_comment_files_from_ruby_source_code(filename)
  source_code = File.read(filename)
  todo_comments = ruby_source_code.find_todo_comments(source_code)
  other_comments = ruby_source_code.find_other_comments(source_code)
  File.open("todos.txt", "w") { |f|f.print todo_comments }
  File.open("others.txt", "w") { |f|f.print other_comments }
end

コードのギャップを埋める

あらかじめ識別しておいたメッセージ、ロールに近づけます。
抽象度がそろいました。

def output_comment_files_from_ruby_source_code(filename)
  source_code = read_source_code(filename)
  todo_comments = ruby_source_code.find_todo_comments(source_code)
  other_comments = ruby_source_code.find_other_comments(source_code)
  write_todos(todo_comments)
  write_others(other_comments)
end

def read_source_code(filename)
  File.read(filename)
end

def write_todos(todo_comments)
  write_file("todos.txt", todo_comments)
end

def write_others(other_comments)
  write_file("others.txt", other_comments)
end

def write_file(filename, contents)
  File.open("others.txt", "w") { |f|f.print other_comments }
end