Qual é a diferença entre print e puts?

Respostas:

377

puts adiciona uma nova linha ao final de cada argumento, se ainda não houver uma.

print não adiciona uma nova linha.


Por exemplo:

puts [[1,2,3], [4,5,nil]] Retornaria:

1
2
3
4
5

Considerando print [[1,2,3], [4,5,nil]] que retornaria:

[[1,2,3], [4,5, zero]]
Observe como o put não gera o valor nulo, ao contrário o print.
mikewilliamson
fonte
88
Na verdade, uma nova linha após cada argumento. Esse é um ponto-chave e não está claro nos documentos do Ruby (já que o exemplo tem apenas 1 argumento).
cdunn2001
3
Há outra coisa ... estenda a classe da matriz e substitua o método to_s. se coloca não usar os novos to_s para um objeto de sua nova classe, enquanto print faz
kapv89
1
usar irb 0.9.5 puts ("a") e puts ("a \ n") têm exatamente a mesma saída no REPL.
Marcus Junius Brutus
@ kapv89 Isso não é verdade: eu apenas tentei e ambos os métodos de impressão usam o método to_s. Apenas p não usa.
collimarco
6
@Ronker, isso ainda é apenas um argumento. O compilador concatena seqüências de caracteres adjacentes.
cdunn2001
61

Uma grande diferença é se você estiver exibindo matrizes. Especialmente aqueles com NIL. Por exemplo:

print [nil, 1, 2]

[nil, 1, 2]

mas

puts [nil, 1, 2]

1
2

Observe que nenhum item nulo aparece (apenas uma linha em branco) e cada item em uma linha diferente.

MBentley
fonte
1
Eu notei isso hoje, o que me trouxe aqui. Eu adoraria saber o que pensar sobre isso. Parece ser um caso especial de put para lidar com matrizes assim. Pensando em qual era a lógica ... É apenas para ser análogo a outras línguas?
Dan Barron
Faz sentido, uma vez que o put será exibido com uma nova linha, para que você possa pensar nele como iterando no array e chamando put em cada linha ... é estranho, no entanto, que ele não nil
exiba
42

printgera cada argumento, seguido por $,, para $stdout, seguido por $\. É equivalente aargs.join($,) + $\

putsdefine ambos $,e $\como "\ n" e, em seguida, faz o mesmo que print. A principal diferença é que cada argumento é uma nova linha puts.

Você pode require 'english'acessar essas variáveis ​​globais com nomes fáceis de usar .

wersimmon
fonte
boa dica sobre a englishlib
lacostenycoder
18

Os documentos da API dão algumas boas dicas:

print() → nil

print(obj, ...) → nil

Grava o (s) objeto (s) fornecido (s) no ios . Retorna nil.

O fluxo deve ser aberto para gravação. Cada objeto que não é uma string será convertido chamando seu to_smétodo. Quando chamado sem argumentos, imprime o conteúdo de $_.

Se o separador do campo de saída ( $,) não for nil, ele será inserido entre os objetos. Se o separador de registros de saída ( $\) não estiver nil, ele será anexado à saída.

...

puts(obj, ...) → nil

Grava o (s) objeto (s) fornecido (s) no ios . Grava uma nova linha após qualquer que ainda não termine com uma sequência de nova linha. Retorna nil.

O fluxo deve ser aberto para gravação. Se chamado com um argumento de matriz, grava cada elemento em uma nova linha. Cada objeto que não é uma string ou matriz será convertido chamando seu to_smétodo. Se chamado sem argumentos, gera uma única nova linha.

Experimentando um pouco os pontos acima, as diferenças parecem ser:

  • Chamado com vários argumentos, os printsepara pelo 'separador de campo de saída' $,(que não é o padrão) e os putssepara por novas linhas. putstambém coloca uma nova linha após o argumento final, enquanto printnão.

    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
  • putsdescompacta automaticamente matrizes, enquanto printnão:

    2.1.3: 001> print [1, [2, 3]], [4]
    [1, [2, 3]] [4] => nulo 
    2.1.3: 002> coloca [1, [2, 3]], [4]
    1
    2
    3
    4
     => nulo
  • printsem argumentos imprime $_(a última coisa lida por gets), enquanto putsimprime uma nova linha:

    2.1.3 :001 > gets
    hello world
     => "hello world\n" 
    2.1.3 :002 > puts
    
     => nil 
    2.1.3 :003 > print
    hello world
     => nil
  • printgrava o separador de registros de saída $\após o que imprimir, enquanto putsignora esta variável:

    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
Mark Amery
fonte
4

putschame o to_sde cada argumento e adicione uma nova linha a cada string, se não terminar com a nova linha. printbasta gerar cada argumento chamando de to_s.

por exemplo puts "one two":: one two

{nova linha}

puts "one two\n": one two

{new line} #puts não adicionará uma nova linha ao resultado, pois a string termina com uma nova linha

print "one two": one two

print "one two\n": one two

{nova linha}

E há outra maneira de produzir: p

Para cada objeto, escreve diretamente obj.inspect seguido por uma nova linha na saída padrão do programa.

É útil gerar uma mensagem de depuração. p "aa\n\t":aa\n\t

ryan
fonte
-1

Se você deseja putsgerar uma matriz dentro da string usando , obterá o mesmo resultado como se estivesse usando print:

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

Mas se não estiver dentro de uma string citada, sim. A única diferença é entre a nova linha quando usamos puts.

user2273663
fonte
1
-1 por dois motivos. Em primeiro lugar, falta de clareza: não entendo o que o "Mas ..." inicial pretende seguir adiante, nem entendo a que o "sim" no parágrafo final está respondendo. Em segundo lugar, por falta de correção: você diz que usar no printflugar do putscódigo de exemplo dará o mesmo resultado, mas na verdade não. A putsvariante adiciona uma nova linha no final, enquanto a printfoutra não, exatamente como no caso em que não há matriz interpolada na cadeia. (Necessariamente assim, uma vez que a interpolação acontece quando se avalia o literal string.)
Mark Amery
Aha! Depois de ler outras respostas, acho que entendi - você pretendia que fosse uma resposta para stackoverflow.com/a/14534145/1709587 ? De qualquer forma, ele realmente não tem uma resposta por si só.
Mark Amery