web-dev-qa-db-ja.com

to_s対to_str(およびto_i / to_a / to_h対to_int / to_ary / to_hash)Ruby

私はRubyと私は少し混乱させているいくつかのメソッドを見てきました。特にto_s vs to_str(および同様に、to_i/to_intto_a/to_ary、&to_h/to_hash)。読んだことから、短い形式(例:to_s)は明示的な変換用で、長い形式は暗黙的な変換用です。

to_strが実際にどのように使用されるのか、私にはよくわかりません。 String以外の何かがto_strを定義することはありますか?この方法の実用的なアプリケーションを提供できますか?

64
Jeff Storey

最初に、このすべてが「ショート」の各ペアに適用されることに注意してください(例:to_s/to_i/to_a/to_h)対“ long”(例:to_str/to_int/to_ary/to_hash)Ruby(それぞれのタイプ))の強制メソッドはすべて同じセマンティクスを持っているため。


それらは異なる意味を持っています。オブジェクトactsが文字列でrepresentableであるのではなく、文字列のように動作しない限り、to_strを実装しないでください。 to_strを実装する唯一のコアクラスはString自体です。

Rubyのプログラミング( このブログ投稿 から引用、すべて読む価値がある):

[to_iおよびto_s]は特に厳密ではありません。たとえば、オブジェクトに何らかの適切な文字列表現がある場合、おそらくto_sメソッドがあります…[to_intおよびto_str]は厳密な変換関数です。文字列または整数を使用できるすべての場所で[your]オブジェクトを自然に使用できる場合にのみ実装します。

旧Ruby Pickaxeのドキュメント には次のように書かれています:

ほとんどすべてのクラスでサポートされているto_sとは異なり、to_strは通常、文字列のように動作するクラスによってのみ実装されます。

たとえば、 整数 に加えて、両方とも 浮動数値to_intto_iに相当するto_str)両方とも整数を簡単に置き換えることができるため(これらはすべて実際には数字です)。クラスがStringと同様に緊密な関係にない限り、to_strを実装しないでください。

77
Andrew Marshall

_to_s_/_to_str_を使用/実装する必要があるかどうかを理解するために、いくつかの例を見てみましょう。 これらの方法が失敗したときを考慮することは明らかです。

_1.to_s              # returns "1"
Object.new.to_s     # returns "#<Object:0x4932990>"
1.to_str            # raises NoMethodError
Object.new.to_str   # raises NoMethodError
_

ご覧のとおり、_to_s_はany objectを文字列に変換できます。一方、_to_str_ エラーを発生させるパラメーターが文字列に見えない場合。


では、_Array#join_を見てみましょう。

_[1,2].join(',')     # returns "1,2"
[1,2].join(3)       # fails, the argument does not look like a valid separator.
_

_Array#join_は、結合する前に配列内の項目(実際に何であれ)を文字列に変換するので便利です。したがって、_Array#join_はそれらに対して_to_s_を呼び出します。

ただし、区切り文字は文字列であると想定されています-[1,2].join(3)を呼び出している人は間違いを犯している可能性が高い。これが、_Array#join_がセパレータで_to_str_を呼び出す理由です。


同じ原則が他の方法にも当てはまるようです。ハッシュで_to_a_/_to_ary_を検討してください:

_{1,2}.to_a      # returns [[1, 2]], an array that describes the hash
{1,2}.to_ary    # fails, because a hash is not really an array.
_

要約すると、これは私がそれを見る方法です:

  • _to_s_を呼び出して、オブジェクトを説明する文字列を取得します。
  • _to_str_を呼び出して、オブジェクトが実際に文字列のように動作することを確認します。
  • オブジェクトを記述する文字列を作成できる場合は、_to_s_を実装します。
  • オブジェクトが文字列のように完全に動作できる場合は、_to_str_を実装します。

_to_str_を自分で実装できるケースは、おそらくColoredStringクラス-色が付けられた文字列だと思います。色付きのコンマをjoinに渡すのが間違いではなく、結果として_"1,2"_(その文字列が色付けされない場合でも)になることが明らかな場合は、doColoredStringに_to_str_を実装します。

19

Zverok には、何をいつ使用するかについてのわかりやすい記事があります(to_hおよびto_hashで説明)。

これらのメソッドを実装するオブジェクトを文字列に変換できるかどうかを行う必要があります-> use to_s
またはそれは何らかの(拡張)文字列のタイプです-> use to_str


GemのConfigurationクラスで実際にto_hashの意味のある使用法を見てきました 'configuration' (- GitHub および Configuration.rb

これは、名前が示すように、提供された構成を表します。実際には、構成に変換するのではなく、(追加機能を備えた)一種のハッシュです。

0
dCSeven