ทับทิมp
และputs
ทับทิมต่างกันไหม?
ทับทิมp
และputs
ทับทิมต่างกันไหม?
คำตอบ:
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 inspect
. อย่างที่ฉันบอกว่าเป็นวิธีการทางเลือกสตริงซึ่งผลิตผลลัพธ์ที่เหมาะสมสำหรับการแก้จุดบกพร่อง เมื่อเสร็จสิ้นการดีบักคุณควรลบข้อความสั่งการดีบัก (หรือสำหรับโครงการที่จริงจังกว่านี้คุณควรใช้กรอบการบันทึกและไม่ใช้ p หรือทำให้การดีบักเลย) ความจริงที่ว่าp
วัตถุที่ส่งคืนดูเหมือนไม่เกี่ยวข้องในสถานการณ์ส่วนใหญ่ (และฉันเชื่อว่าฉันให้คำตอบนี้ก่อนหน้านี้เป็นกรณี) ความแตกต่างในผลลัพธ์เป็นความแตกต่างหลัก (และเคยเป็นเพียงคนเดียว)
นอกจากนี้ยังเป็นสิ่งสำคัญที่จะต้องทราบว่า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
โทร แต่ไม่ชัดเจนในทางปฏิบัติ
p foo
เป็นเช่นเดียวกับ puts foo.inspect
puts
คืนค่าnil
แทนที่จะ foo
เป็นเช่นp
นั้น
puts foo.inspect; foo
(-> {p "Hello World"}.call) == (-> {puts "Hello World".inspect}.call )
. upvotes จำนวนมากไม่ได้ทำให้คำตอบนี้ดี!
นอกเหนือจากคำตอบข้างต้นแล้วยังมีความแตกต่างเล็กน้อยในเอาต์พุตคอนโซล - นั่นคือการมี / ไม่มีเครื่องหมายจุลภาค / อัญประกาศคว่ำ - ที่มีประโยชน์:
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
>> ******
puts(obj, ...) → nil
เขียนวัตถุที่กำหนดไปยัง ios เขียนขึ้นบรรทัดใหม่หลังจากที่ไม่ได้ลงท้ายด้วยลำดับการขึ้นบรรทัดใหม่ ผลตอบแทนที่ศูนย์
ต้องเปิดสตรีมเพื่อการเขียน หากถูกเรียกพร้อมกับอาเรย์ อาร์กิวเมนต์ให้เขียนแต่ละองค์ประกอบในบรรทัดใหม่ แต่ละวัตถุที่กำหนดที่ไม่ใช่สตริงหรืออาร์เรย์จะถูกแปลงโดยการเรียก
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
( ตรวจสอบให้มุมมองที่แท้จริงของวัตถุมากกว่าวิธีto_s )
(->{p "Hello World"}.call) == (-> {puts "Hello World".inspect}.call )
ซึ่งอาจแสดงให้เห็นถึงหนึ่งของความแตกต่างที่สำคัญซึ่งเป็นที่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)