В чем разница между печатью и путами?

Ответы:

377

puts добавляет новую строку в конец каждого аргумента, если его еще нет.

print не добавляет новую строку.


Например:

puts [[1,2,3], [4,5,nil]] Вернется:

1
2
3
4
5

Принимая во внимание, print [[1,2,3], [4,5,nil]] что вернется:

[[1,2,3], [4,5, ноль]]
Обратите внимание, что put не выводит значение nil, а print -.
mikewilliamson
источник
88
Собственно, перевод строки после каждого аргумента. Это ключевой момент, который не ясен из документации по Ruby (поскольку в примере только 1 аргумент).
cdunn2001
3
Есть еще одна вещь ... расширить класс массива и переопределить метод to_s. Put не использует новые to_s для объекта вашего нового класса, в то время как print делает
kapv89
1
при использовании irb 0.9.5 put ("a") и put ("a \ n") имеют одинаковые выходные данные в REPL.
Маркус Юний Брут
@ kapv89 Это не правда: я только что попробовал, и оба помещают электронную печать, используя метод to_s. Только р не использует его.
collimarco
6
@ Фронкер, это всего лишь один аргумент. Компилятор объединяет смежные строки.
cdunn2001
61

Большая разница, если вы отображаете массивы. Особенно те, с NIL. Например:

print [nil, 1, 2]

дает

[nil, 1, 2]

но

puts [nil, 1, 2]

дает

1
2

Обратите внимание, что ни один элемент не отображается (просто пустая строка) и каждый элемент находится на отдельной строке.

MBentley
источник
1
Я заметил это сегодня, что привело меня сюда. Я хотел бы знать, что думают об этом. Кажется, это особый случай для путов для обработки таких массивов. Хотите знать, каково было обоснование ... Это просто быть аналогом другим языкам?
Дэн Баррон
Это имеет смысл, так как put будет выводить с новой строкой, поэтому вы можете думать об этом как об итерациях по массиву и вызове put в каждой строке ... однако странно, что он не выводитnil
Muers
42

printвыводит каждый аргумент, затем $,, до $stdout, затем $\. Это эквивалентноargs.join($,) + $\

putsустанавливает оба параметра $,и $\\ n, а затем делает то же самое, что и print. Главное отличие в том, что каждый аргумент представляет собой новую строку с puts.

Вы можете require 'english'получить доступ к этим глобальным переменным с понятными именами .

wersimmon
источник
хороший совет по englishlib
lacostenycoder
18

Документы API дают несколько полезных советов:

print() → nil

print(obj, ...) → nil

Записывает данный объект (ы) в ios . Возвращает nil.

Поток должен быть открыт для записи. Каждый данный объект, который не является строкой, будет преобразован путем вызова его to_sметода. При вызове без аргументов печатает содержимое $_.

Если разделитель выходного поля ( $,) отсутствует nil, он вставляется между объектами. Если разделитель выходной записи ( $\) отсутствует nil, он добавляется к выводу.

...

puts(obj, ...) → nil

Записывает данный объект (ы) в ios . Записывает новую строку после любой, которая еще не заканчивается последовательностью новой строки. Возвращает nil.

Поток должен быть открыт для записи. При вызове с аргументом массива записывает каждый элемент в новую строку. Каждый данный объект, который не является строкой или массивом, будет преобразован путем вызова его to_sметода. Если вызывается без аргументов, выводится одна новая строка.

Немного поэкспериментировав с пунктами, приведенными выше, различия кажутся:

  • Вызывается с несколькими аргументами, printразделяет их «разделителем выходного поля» $,(который по умолчанию не имеет значения), а putsразделяет их переводом строки. putsтакже ставит новую строку после последнего аргумента, пока printнет.

    2.1.3 :001 > print 'hello', 'world'
    helloworld => nil 
    2.1.3 :002 > puts 'hello', 'world'
    hello
    world
     => nil
    2.1.3 :003 > $, = 'fanodd'
     => "fanodd" 
    2.1.3 :004 > print 'hello', 'world'
    hellofanoddworld => nil 
    2.1.3 :005 > puts 'hello', 'world'
    hello
    world
     => nil
  • putsавтоматически распаковывает массивы, пока printне:

    2.1.3: 001> распечатать [1, [2, 3]], [4]
    [1, [2, 3]] [4] => ноль 
    2.1.3: 002> ставит [1, [2, 3]], [4]
    1
    2
    3
    4
     => ноль
  • printбез аргументов печатает $_(последнее, что прочитано gets), а putsпечатает новую строку:

    2.1.3 :001 > gets
    hello world
     => "hello world\n" 
    2.1.3 :002 > puts
    
     => nil 
    2.1.3 :003 > print
    hello world
     => nil
  • printзаписывает разделитель выходной записи $\после того, что он печатает, putsигнорируя эту переменную:

    mark@lunchbox:~$ irb
    2.1.3 :001 > $\ = 'MOOOOOOO!'
     => "MOOOOOOO!" 
    2.1.3 :002 > puts "Oink! Baa! Cluck! "
    Oink! Baa! Cluck! 
     => nil 
    2.1.3 :003 > print "Oink! Baa! Cluck! "
    Oink! Baa! Cluck! MOOOOOOO! => nil
Марк Эмери
источник
4

putsВызовите to_sкаждый аргумент и добавьте новую строку в каждую строку, если она не заканчивается новой строкой. printпросто выведите каждый аргумент, вызвав их to_s.

например puts "one two": one two

{новая линия}

puts "one two\n": one two

{новая строка} #puts не добавит новую строку в результат, так как строка заканчивается новой строкой

print "one two": one two

print "one two\n": one two

{новая линия}

И есть еще один способ вывода: p

Для каждого объекта непосредственно записывает obj.inspect, за которым следует новая строка в стандартный вывод программы.

Это полезно для вывода отладочного сообщения. p "aa\n\t":aa\n\t

Райана
источник
-1

Если вы хотите вывести массив внутри строки используя puts, вы получите тот же результат, что и при использовании print:

puts "#{[0, 1, nil]}":
[0, 1, nil]

Но если нет строки в кавычках, тогда да. Единственная разница между новой строкой, когда мы используем puts.

user2273663
источник
1
-1 по двум причинам. Во-первых, отсутствие ясности: я не понимаю, из-за чего здесь подразумевается первоначальное «Но ...», и не понимаю, на что отвечает «да» в последнем абзаце. Во-вторых, из-за отсутствия правильности: вы говорите, что использование printfвместо putsкода в вашем примере даст тот же результат, но на самом деле это не так. putsВариант добавляет символ новой строки в конце в то время как printfодин не делает, так же , как случай , когда нет никакого массива интерполированного в строку. (Обязательно, так как интерполяция происходит при оценке строкового литерала.)
Марк Эмери
Ага! Прочитав другие ответы, я понял, что понял - вы хотели, чтобы это был ответ на stackoverflow.com/a/14534145/1709587 ? В любом случае, это действительно не ответ на свой вопрос.
Марк Амери