Відповіді:
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)