「Rubyベストプラクティス」を読む2


2章はメソッドの作り方に関する章。
良いメソッドを書くための、引数やブロックの使い方が書かれています。

色々なメソッドの引数処理

# 標準的な引数
def distance(x1, y1, x2, y2)
  Math.hypot(x2-x1, y2-y1)
end

# オプションパラメータのある引数
def load_file(name, mode="rb")
  File.open(name, mode)
end

# 疑似キーワード引数
# 下のように呼べる
# story(animal: "Tiger", person: "Yankee Doodle")
def story(options)
  # デフォルト値を持たせて、mergeするやり方もある。
  options = {person: "person", animal: "animal"}.merge(options)
  "#{options[:person]} went to town, riding on a #{option[:animal]}}"
end

# 引数を配列として使う
def distance2(*points)
  distance(*points.flatten)
end

ブロックを使う

イテレートとか、前処理や後処理があるメソッドはブロックを使うようにすると綺麗になる。
イテレートのメソッドを定義するときは、Enumerableが使えるか検討する。
コールバックもブロックを使ってできる。&blockでブロックを受け取り、あとで呼び出す。
また、以下のようにinstance_evalを使って、APIをきれいにできる。

# 以下のようなコードで使用するオブジェクトがあるとする
# server = Server.new
# server.handle(/hello/){"hello"}
# server.handle(/bye/){"bye"}
# server.run
#
# instance_evalを使って、以下のように呼び出せるようにする
# Server.run do
#   handle(/hello/){"hello"}
#   handle(/bye/){"bye"}
# end

class Server
  def self.run(port=3333, &block)
    server = Server.new(port)
    server.instance_eval(&block)
    server.run
  end
end