回答:
p foo
のfoo.inspect
後に改行が表示されます。つまり、のinspect
代わりにの値が出力されます。to_s
これは、デバッグにより適しています(たとえば1
、"1"
との違い"2\b1"
を確認できるため、なしで印刷する場合は区別できませんinspect
)。
p
はオブジェクトの値も返しますが、返さないことに注意してくださいputs
。1.9.3p125 :002 > (p "foo").class "foo" => String 1.9.3p125 :003 > (puts "foo").class foo => NilClass
to_s
は、Rubyの標準のto-stringメソッドです。inspect
。言ったように、これは文字列に代わる方法で、デバッグにより適した出力を生成します。デバッグが完了したら、デバッグステートメントを明らかに削除する必要があります(または、より深刻なプロジェクトでは、おそらくロギングフレームワークを使用し、pまたはputsをデバッグに使用しないでください)。p
オブジェクトを返すという事実は、ほとんどの状況では無関係であるように思われます(これが事実になる前に私がこの答えを出したと私は信じています)。出力の違いが主な違いです(かつては唯一の違いでした)。
p foo
と同じです puts foo.inspect
puts
返すのnil
ではなく、 foo
を返しますp
。
puts foo.inspect; foo
(-> {p "Hello World"}.call) == (-> {puts "Hello World".inspect}.call )
。多くの賛成投票では、これは良い答えにはなりません!
上記の回答に加えて、コンソール出力には微妙な違いがあります。つまり、反転カンマ/引用符の有無です。
p "+++++"
>> "+++++"
puts "====="
>> =====
親戚のprintを使用して単純なプログレスバーを作成したい場合、これは便利です。
array = [lots of objects to be processed]
array.size
>> 20
これにより、100%の進行状況バーが表示されます。
puts "*" * array.size
>> ********************
そして、これは各反復で増分*を追加します:
array.each do |obj|
print "*"
obj.some_long_executing_process
end
# This increments nicely to give the dev some indication of progress / time until completion
>> ******
puts(obj, ...) → nil
指定されたオブジェクトをiosに書き込みます。改行シーケンスでまだ終了していない改行を書き込みます。nilを返します。
書き込み用にストリームを開く必要があります。配列 引数を指定して呼び出された場合、各要素を新しい行に書き込みます。文字列または配列ではない指定された各オブジェクトは、その
to_s
メソッドを呼び出すことによって変換されます。引数なしで呼び出された場合、単一の改行を出力します。
IRBで試してみましょう
# always newline in the end
>> puts # no arguments
=> nil # return nil and writes a newline
>> puts "sss\nsss\n" # newline in string
sss
sss
=> nil
>> puts "sss\nsss" # no newline in string
sss
sss
=> nil
# for multiple arguments and array
>> puts "a", "b"
a
b
=> nil
>> puts "a", "b", ["c", "d"]
a
b
c
d
=> nil
p(obj) → obj click to toggle source
p(obj1, obj2, ...) → [obj, ...]
p() → nil
オブジェクトごとobj.inspect
に、プログラムの標準出力に改行を続けて直接書き込みます。
IRBで
# no arguments
>> p
=> nil # return nil, writes nothing
# one arguments
>> p "sss\nsss\n"
"sss\nsss\n"
=> "aaa\naaa\n"
# multiple arguments and array
>> p "a", "b"
"a"
"b"
=> ["a", "b"] # return a array
>> p "a", "b", ["c", "d"]
"a"
"b"
["c", "d"]
=> ["a", "b", ["c", "d"]] # return a nested array
これら2つは等しい:
p "Hello World"
puts "Hello World".inspect
(inspectは、to_sメソッドと比較して、オブジェクトのよりリテラルなビューを提供します)
(->{p "Hello World"}.call) == (-> {puts "Hello World".inspect}.call )
これp
は、渡されたものの値を返すという主な違いの1つを示している可能性がありputs
ますnil
。
def foo_puts
arr = ['foo', 'bar']
puts arr
end
def foo_p
arr = ['foo', 'bar']
p arr
end
a = foo_puts
=>nil
a
=>nil
b = foo_p
=>['foo', 'bar']
b
['foo', 'bar']
ベンチマーク番組puts
は遅い
require 'benchmark'
str = [*'a'..'z']
str = str*100
res = Benchmark.bm do |x|
x.report(:a) { 10.times {p str} }
x.report(:b) { 10.times {puts str} }
end
puts "#{"\n"*10}"
puts res
0.010000 0.000000 0.010000 ( 0.047310)
0.140000 0.090000 0.230000 ( 0.318393)