Відповіді:
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 або put для налагодження). Той факт, що 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 "====="
>> =====
Я вважаю це корисним, якщо ви хочете зробити просту панель прогресу, використовуючи друк :
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наступний новий рядок до стандартного виходу програми.
в ірб
# 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повертає значення того, що передається йому, де як 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)