0

次のコードにはRuby1.8.6を使用しています。

# Create an array and override the #to_s on that object
thing = [1,2,3]
def thing.to_s
  'one'
end

print "Using print: "
print thing

puts
puts "Using puts: "
puts thing

出力:

Using print: one
Using puts: 
1
2
3

つまり、物事配列であり、私は物事#to_sをオーバーライドしました。printはオーバーライドされた実装を使用しているようですが、putsは使用していません。なんで?

Kernel#putsとKernel#print(C実装)のソースコードをたどったところ、それらが非常に異なる実装であることがわかりました。この背後にある設計上の決定(もしあれば)は何でしょうか?

ちなみに、私が書いた別のクラスのインスタンスとして(または私が試したHash / String / other-classesとして)ものを作成する場合、printとputsの両方がto_sのオーバーライドされた実装を使用します。

4

2 に答える 2

3

おやおや...これはすでに、ruby-talkメーリングリスト、ruby-coreメーリングリスト、および膨大な数のブログで数え切れないほどのスレッドのトピックになっています。

その要点は、そのputs特殊なケースArrayです。なぜそれがそれらを特別なものにするのか、なぜそれがそれらだけを特別なものにするのか(たとえば、すべてではなくEnumerable)、なぜそれがそれらを特別なものにするのか(そして、言うのではないprint)、誰も本当に知りません。それがその通りです。

ところで、あなたがPOLSについて言及したので、Rubyコミュニティは、POLSがmatzにのみ適用されることを常に非常に明確にしてきました。つまり、Rubyは驚くべきことではありません。あなたや私や他の誰かが驚いたとしても、それは重要ではありません。

于 2009-12-30T03:06:53.990 に答える
2

Rubyプログラミング言語から:
代替テキストhttp://ecx.images-amazon.com/images/I/41n-JSlBHkL._SL75_.jpg

文字列や配列と同様に、出力ストリームは追加可能であり、<<演算子を使用してそれらに値を書き込むことができます。puts最も一般的な出力方法の1つです。それぞれの引数を文字列に変換し、それぞれをストリームに書き込みます。文字列がまだ改行文字で終わっていない場合は、改行文字が追加されます。putsへの引数のいずれかが配列である場合、配列は再帰的に展開され、各要素は、putsへの引数として直接渡されたかのように独自の行に出力されます。このprintメソッドは引数を文字列に変換し、それらをストリームに出力します。グローバルフィールドセパレーター$がデフォルト値の。から変更された場合、nilその値は。への各引数の間に出力されますprint。出力レコード区切り文字の場合$/がデフォルト値の。から変更された場合nil、すべての引数が出力された後にその値が出力されます。

デザインの決定に関しては、私にはわかりません。

于 2009-12-30T01:11:48.650 に答える