Apakah ada perbedaan antara pdan putsdi Ruby?
Apakah ada perbedaan antara pdan putsdi Ruby?
Jawaban:
p foocetakan foo.inspectdiikuti oleh baris baru, yaitu mencetak nilai inspectalih - alih to_s, yang lebih cocok untuk debugging (karena Anda dapat misalnya membedakan antara 1, "1"dan "2\b1", yang Anda tidak dapat saat mencetak tanpa inspect).
pjuga mengembalikan nilai objek, sementara putstidak. 1.9.3p125 :002 > (p "foo").class "foo" => String 1.9.3p125 :003 > (puts "foo").class foo => NilClass
to_sadalah metode to-string standar di Ruby. inspect. seperti yang saya katakan, adalah metode alternatif ke-string, yang menghasilkan output yang lebih cocok untuk debugging. Setelah menyelesaikan debugging Anda harus menghapus pernyataan debugging Anda (atau untuk proyek yang lebih serius Anda mungkin harus menggunakan kerangka kerja logging dan tidak menggunakan p atau menempatkan untuk debugging sama sekali). Fakta yang pmengembalikan objek tampaknya tidak relevan dalam kebanyakan situasi (dan saya percaya saya memberikan jawaban ini sebelum ini terjadi). Perbedaan dalam output adalah perbedaan utama (dan dulunya satu-satunya).
Penting juga untuk dicatat bahwa puts"bereaksi" ke kelas yang telah to_sdidefinisikan, ptidak. Sebagai contoh:
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>
Ini mengikuti langsung dari .inspectpanggilan, tetapi tidak jelas dalam praktiknya.
p foo sama dengan puts foo.inspect
putskembali nil, bukan fooseperti halnya p.
puts foo.inspect; foo
(-> {p "Hello World"}.call) == (-> {puts "Hello World".inspect}.call ) . Banyak upvotes TIDAK membuat ini jawaban yang bagus!
Selain jawaban di atas, ada perbedaan halus dalam output konsol - yaitu ada / tidak adanya tanda koma / tanda kutip - yang dapat berguna:
p "+++++"
>> "+++++"
puts "====="
>> =====
Saya menemukan ini berguna jika Anda ingin membuat progress bar sederhana, menggunakan kerabat dekatnya, cetak :
array = [lots of objects to be processed]
array.size
>> 20
Ini memberikan bilah kemajuan 100%:
puts "*" * array.size
>> ********************
Dan ini menambahkan * inkremental pada setiap iterasi:
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
>> ******
Dari dokumen ruby-2.4.1
puts(obj, ...) → nilMenulis objek yang diberikan ke ios. Menulis baris baru setelah yang belum berakhir dengan urutan baris baru. Pengembalian nihil .
Aliran harus dibuka untuk ditulis. Jika dipanggil dengan argumen array , tulis setiap elemen pada baris baru. Setiap objek yang diberikan bukan string atau array akan dikonversi dengan memanggil
to_smetodenya. Jika dipanggil tanpa argumen, menghasilkan satu baris baru.
ayo coba di 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
Untuk setiap objek, tulis langsungobj.inspectdiikuti oleh baris baru ke output standar program.
di 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
Ini 2 adalah sama:
p "Hello World"
puts "Hello World".inspect
( inspect memberikan pandangan objek yang lebih literal dibandingkan dengan metode to_s )
(->{p "Hello World"}.call) == (-> {puts "Hello World".inspect}.call )
Ini dapat menggambarkan salah satu perbedaan utama yaitu pmengembalikan nilai dari apa yang diteruskan ke sana, di mana sebagai putspengembalian 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']
Pertunjukan benchmark putslebih lambat
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)