puts と print の Array に関する違い

リファレンスを見ると、

puts(*arg) -> nil
引数と改行を順番に 標準出力 $stdout に出力します。引数がなければ改行のみを出力します。

引数が配列の場合、その要素と改行を順に出力します。配列や文字列以外のオブジェクトが引数として与えられた場合には、当該オブジェクトを最初に to_ary により配列へ、次に to_s メソッドにより文字列へ変換を試みます。末尾が改行で終っている引数や配列の要素に対しては puts 自身は改行を出力しません。

print(*arg) -> nil
引数を順に標準出力 $stdout に出力します。引数が与えられない時には変数 $_ の値を出力します。

文字列以外のオブジェクトが引数として与えられた場合には、 to_s メソッドにより文字列に変換してから出力します。

変数 $, (出力フィールドセパレータ)に nil でない値がセットされている時には、各引数の間にその文字列を出力します。変数 $\ (出力レコードセパレータ)に nil でない値がセットされている時には、最後にそれを出力します。

Array が引数の場合、改行などのセパレーター関連を除くと、違いは太字の部分。引数が Array の時にいきなり to_s を呼ぶか、配列要素を順に出力するか。Array#to_s は、Array#inspect なので違いが出る。

#!/usr/local/bin/ruby
# encoding: utf-8
$\="\n"
str = "あいうえお"
str.force_encoding("US-ASCII")
puts  str    #=> あいうえお
print str    #=> あいうえお
puts  [str]  #=> あいうえお
print [str]  #=> ["\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86\xE3\x81\x88\xE3\x81\x8A"]