p vs放入Ruby

在Ruby中,pputs有什么区别吗?

71849 次浏览

p foo输出foo.inspect后跟换行符,即输出inspect的值,而不是to_s,这更适合调试(因为例如,你可以区分1"1""2\b1"之间的区别,如果没有inspect,则无法进行打印)。

p fooputs foo.inspect相同

同样重要的是要注意,puts“响应”一个定义了to_s的类,而p没有。例如:

class T
def initialize(i)
@i = i
end
def to_s
@i.to_s
end
end


t = T.new 42
puts t   => 42
p t      => #<T:0xb7ecc8b0 @i=42>

这直接来自.inspect调用,但在实践中并不明显。

ruby-2.4.1文档

puts(obj, ...) → nil

将给定对象写入ios。在任何后面写入换行符 do 不是已经以换行符结束。返回nil . < / p >

必须打开流以便写入。如果使用数组调用 参数,在新行上写入每个元素。每个给定对象 不是字符串或数组的对象将通过调用其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

< p > p(obj) → obj click to toggle source < br > p(obj1, obj2, ...) → [obj, ...] p() → nil < br > 对于每个对象,直接将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

除了上面的答案,在控制台输出中有一个微妙的差异——即存在/不存在倒逗号/引号——这可能是有用的:

p "+++++"
>> "+++++"


puts "====="
>> =====

我发现如果你想用它们的近亲打印来做一个简单的进度条,这个方法很有用:

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
>> ******

这两个相等:

p "Hello World"
puts "Hello World".inspect

(与to_s方法相比,检查给出了更多的对象文字视图)

这可能说明了一个关键的区别,即p返回传递给它的值,而作为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)

p方法将打印更广泛的可调试消息,其中puts将修饰消息代码。

例:请看下面的代码行:

msg = "hey, Use \#{ to interpolate expressions"
puts msg #clean msg
p msg #shows \ with #

输出将是

hey, Use #{ to interpolate expressions
"hey, Use \#{ to interpolate expressions"

见输出pic更清晰