Tbpgr Blog

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

Ruby | Collecting Inputs | Use symbols as placeholder object

概要

Use symbols as placeholder object

前提

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

当記事は上記のうち、Collecting Inputsに関する話です。

詳細

状況

オプショナルのcollaboratorはメソッドがどのように呼ばれるかに依存して使われないかもしれない。
例えば、WebAPIと通信するメソッドはオプショナルでユーザー認証を受け入れるかもしれない。
しかし、認証が求められたときだけそれらを使う。

概要

nilよりも意味のあるシンボルを用いて、placeholderの値とする。

理由

予期せぬplaceholderの利用は、意味のある・早期の診断済みエラーを発生させる。
(通常、nilが絡んだエラーはどこが原因なのか特定を困難にする。
そのようなエラーが発生した個所の特定を容易にする)

サンプルコード仕様

環境情報を取得するメソッド get_envを作成する。
get_envは下記のような構造のHashを引数にとります。

{env: {languages: [:Java, :Ruby]}})

サンプルコード(適用前)

symbolのplaceholderを利用しない場合。
env keyがない場合に、どこが原因なのかエラーメッセージから特定が困難

def get_env(options = {})
  env = options[:env]
  env.fetch(:languages)
end

hoge = get_env({env: {languages: [:Java, :Ruby]}})

# language keyがない場合
begin
  hoge = get_env({env: {display: :Display}})
rescue => e
  puts e
end

# env keyがない場合
begin
  hige = get_env({})
rescue => e
  puts e
end

出力

key not found: :languages
undefined method `fetch' for nil:NilClass

サンプルコード(適用後)

symbolのplaceholderを利用した場合
env keyがない場合に、どこが原因なのかエラーメッセージから特定が簡単。
:env_not_setで検索すれば該当箇所がすぐに見つかる。

def get_env(options = {})
  env = options.fetch(:env) { :env_not_set }
  env.fetch(:languages)
end

hoge = get_env({env: {languages: [:Java, :Ruby]}})

# language keyがない場合
begin
  hoge = get_env({env: {display: :Display}})
rescue => e
  puts e
end

# env keyがない場合
begin
  hige = get_env({})
rescue => e
  puts e
end

出力

key not found: :languages
undefined method `fetch' for :env_not_set:Symbol