読者です 読者をやめる 読者になる 読者になる

Tbpgr Blog

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

Ruby | Collecting Inputs | Conditionally call conversion methods

概要

Conditionally call conversion methods

前提

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

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

詳細

状況

すべての入力に対して強制せずに変換手続きを使って入力の変換機能を提供したい。
例えばファイル名を扱うメソッドで、ファイル名ではない入力が暗黙敵にファイル名に変換されるようにしたい。

概要

objectが変換手続きに応じることができる場合のみ変換の呼び出しを行う。

理由

変換手続きをオプションサポートすることによって、メソッドが受け入れる入力の幅を広げることができる。

サンプルコード仕様

文字列に「だぜ!」を追加して標準出力する。

クラス固定でチェックした場合のサンプルコード

Stringクラスでチェックすると、Stringクラスでしか利用できません。

class Mrだぜ
  def だぜ(text)
    fail TypeError , "不正なデータ型 #{text.class}" unless text.is_a? String
    print "#{text}だぜ!"
  end
end

Mrだぜ.new.だぜ("田中")

class Person
  attr_reader :name, :age
  def initialize(name, age)
    @name, @age = name, age
  end
end
tanaka = Person.new("tanaka", 43)

# TypeErrorが発生
# Mrだぜ.new.だぜ(tanaka)

出力

田中だぜ!

ビルトインの変換メソッドでチェックした場合のサンプルコード

変換メソッドのto_strがある場合のみto_strが実行されます。

class Mrだぜ
  def だぜ(text)
    text = text.to_str if text.respond_to? :to_str
    puts "#{text}だぜ!"
  end
end

Mrだぜ.new.だぜ("田中")

class Person
  attr_reader :name, :age
  def initialize(name, age)
    @name, @age = name, age
  end

  def to_str
    @name
  end
end

tanaka = Person.new("tanaka", 43)

Mrだぜ.new.だぜ(tanaka)