はじめに
Ruby でコンソールに文字列を出力する際の関数として、print
, puts
, p
が用意されているが、違いについて自分なりにまとめてみた。
確認したバージョン : ruby 2.6.6p146 (2020-03-31 revision 67876) [x64-mingw32]
表示をいろいろ試してみる
print
print
は、文字列をそのまま出力する。オブジェクトが渡された場合は、オブジェクトの.to_s
メソッドで返された文字列を出力する。
print "abc"
print "def"
# => abcdef
改行文字\n
やタブ文字\t
については、シングルクォート'
で囲むと\
をエスケープして文字表示し、ダブルクォート"
で囲むと、それぞれ改行、タブとして解釈して表示する。
print 'a\nb\tc'
# => a\nb\tc # シングルクォートだと、改行、タブを解釈しない
print "d\ne\tf"
# => d # ダブルクォートだと、改行、タブを解釈する
# => e f
配列やハッシュを指定した場合、定義した形式で表示する。
a = [ 1, 2, 3, "4", "5", "abc" ]
b = [ a: "a1", b: "b1", c: "c1" ]
c = [ [1,2], [3,4],5 ]
print a,b,c
# => [1, 2, 3, "4", "5", "abc"][{:a=>"a1", :b=>"b1", :c=>"c1"}][[1, 2], [3, 4], 5]
puts
puts
は、表示のされ方はprint
と同じ。最後に改行が付加されるのが大きな違い。シングルクォートやダブルクォートの扱いも同様。
print "abc"
print "def"
# => abc
# => def
puts 'a\nb\tc'
# => a\nb\tc # シングルクォートだと、改行、タブを解釈しない
puts "d\ne\tf"
# => d # ダブルクォートだと、改行、タブを解釈する
# => e f
配列やハッシュを指定した場合、print
と出力が大きく異なる。配列は要素ごとに展開、改行がついて出力され、文字列にもクォーテーションがつかない。ハッシュの場合は角カッコ[]
無しで表示される。入れ子の配列では、要素がバラバラに表示されることになり、入れ子の情報が把握できない。
a = [ 1, 2, 3, "4", "5", "abc" ]
b = [ a: "a1", b: "b1", c: "c1" ]
c = [ [1,2], [3,4],5 ]
puts a,b,c
# => 1 # 要素が全て展開されて表示
# => 2
# => 3
# => 4 # 文字列のクォーテーションは表示されない。
# => 5
# => abc
# => {:a=>"a1", :b=>"b1", :c=>"c1"} # 角カッコがない。
# => 1 # 入れ子の配列が同じレベルで全部展開される
# => 2
# => 3
# => 4
# => 5
p
p
は、オブジェクトが渡された場合、.to_s
ではなく、.inspect
メソッドで返された文字列を出力する。また、各行の最後に改行が付与される。文字列はダブルクォートで括られて出力されるのが異なる。
p "abc"
p "def"
# => "abc"
# => "def"
改行文字\n
やタブ文字\t
については、改行、タブとして解釈しない。但し、シングルクォート'
で囲むと\
をエスケープしたものを表示し、ダブルクォート"
で囲むと、エスケープしない状態でそのまま文字表示する。
p 'a\nb\tc'
# => "a\\nb\\tc" # \ をエスケープするため、\\ となる。
p "d\ne\tf"
# => "d\ne\tf" # ダブルクォートだと、改行、タブを解釈する
配列やハッシュを指定した場合、定義した形式で表示する。
a = [ 1, 2, 3, "4", "5", "abc" ]
b = [ a: "a1", b: "b1", c: "c1" ]
c = [ [1,2], [3,4],5 ]
p a,b,c
# => [1, 2, 3, "4", "5", "abc"]
# => [{:a=>"a1", :b=>"b1", :c=>"c1"}]
# => [[1, 2], [3, 4], 5]
わかったこと
-
puts
,p
は末尾に改行が自動的に付与されるが、print は末尾に改行が付与されない。 -
p
は、文字列はダブルクォートで括られて出力される。 -
print
,puts
は、改行\n
やタブ\t
等の特殊文字を解釈して表示するが、p
は特殊文字を解釈しないで、そのまま文字列として出力する。 -
print
,p
は、配列やハッシュを定義の通りに表示するが、puts
は配列を展開して要素ごとに改行を付与して表示する。
まとめ
最初、puts
はprint
に改行がつく版、程度に思っていたが、配列表示で大きな違いが出た。配列全体を出力して確認したい場合は、puts
は使わない方がよさそう。
本やネットで、「p
はデバッグ用」という記載が多くみられたが、デバッグの際は特殊文字を解釈しない方が確かに見やすい、文字列か数値かの見分けもつきやすく、入力も簡単なので、確かにデバッグではp
関数で確認するのがベターなんだろう。