概要
明示的変換と暗黙の変換(explicit conversion and implicit conversion)
前提
Confident Rubyではメソッド内の処理を次のように分類しています。
・Collecting Inputs(引数チェック、変換など)
・Performing Work(主処理)
・Delivering Output(戻り値に関わる処理)
・Handling Failure(例外処理)
当記事は上記のうち、Collecting Inputsに関する話です。
詳細
明示的変換と暗黙の変換(explicit conversion and implicit conversion)について。
Stringクラスでいうとto_sが明示的変換,to_strが暗黙的変換にあたります。
to_sは文字列化が主目的。
to_strはStringのダックタイピングが主目的。
Stringのように振る舞わせたいクラスにto_strを実装することで、
暗黙の変換を期待します。
逆に、Stringのように振る舞うクラスを扱うメソッド側では引数に対して
respond_to?でto_strの有無を確認し、
・to_strがなければエラー
・to_strがあれば呼び出して以降の処理を行う
ことで引数がStringクラスであるかチェックする場合と比べて
寛容なインターフェースを提供することができるため、
利用側にとって使いやすくなります。
サンプルコード
to_strの利用例。
仮にPersonクラスを文字列のように振る舞わせたいとします。
class Person attr_reader :name, :age def initialize(name, age) @name, @age = name, age end def to_str @name end end class NotStringPerson attr_reader :name, :age def initialize(name, age) @name, @age = name, age end def to_s @name end end tanaka = Person.new("tanaka", 34) puts tanaka.to_s puts tanaka.to_str # + 演算子利用時に暗黙的にto_strを利用した変換が行われる puts "name = " + tanaka puts "tanaka".include?(tanaka) class StringUser def self.use_string(text) fail 'error!' unless text.respond_to? :to_str text = text.to_str puts text.upcase end end StringUser.use_string("hoge") StringUser.use_string(tanaka) tanaka2 = NotStringPerson.new("tanaka", 34) # raise error # StringUser.use_string(tanaka2)
出力
#<Person:0x25ccad0> tanaka name = tanaka true HOGE TANAKA
参照
to_sの公式ドキュメント
http://docs.ruby-lang.org/ja/2.0.0/method/String/i/to_s.html
to_strの公式ドキュメント
http://docs.ruby-lang.org/ja/2.0.0/method/Object/i/to_str.html
Confident Ruby: Be A Coding Hemingway
http://www.slideshare.net/msalernocyrus/confident-ruby-be-a-coding-hemingway
Matz氏がto_s,to_strに関して発言しているURL群
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/18648
http://www.atdot.net/~ko1/diary/edit_comment.cgi?mode=edit&year=2003&month=12&day=30
http://blade.nagaokaut.ac.jp/cgi-bin/vframe.rb/ruby/ruby-dev/23332?23220-23915