283 votes

<p>vs puts en Ruby</p>

Y a-t-il une différence entre p et puts en Ruby?

347voto

sepp2k Points 157757

p foo imprime foo.inspect suivi d'une nouvelle ligne, c'est-à-dire qu'il imprime la valeur de inspect au lieu de to_s, ce qui est plus adapté pour le débogage (car vous pouvez par exemple faire la différence entre 1, "1" et "2\b1", ce que vous ne pouvez pas faire en imprimant sans inspect).

7 votes

Oui, p (et puts) sont tous deux dans le module Kernel, vous pouvez voir les détails ici : ruby-doc.org/core/classes/Kernel.html#M005961

21 votes

Notez que p renvoie également la valeur de l'objet, tandis que puts ne le fait pas. 1.9.3p125 :002 > (p "foo").class "foo" => String 1.9.3p125 :003 > (puts "foo").class foo => NilClass

3 votes

Excellent résumé fourni par Gareth Rees dans son post intitulé "Ruby p vs puts vs print".

55voto

ezpz Points 5273

Il est également important de noter que puts "réagit" à une classe qui a to_s défini, p ne le fait pas. Par exemple:

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>

Cela découle directement de l'appel à .inspect, mais n'est pas évident en pratique.

38voto

August Lilleaas Points 25812

p foo est la même que puts foo.inspect

6 votes

Mais puts retourne nil, au lieu de foo comme le fait p.

15 votes

C'est faux. C'est la même chose que puts foo.inspect; foo

0 votes

Cela prouve que votre réponse est incorrecte : (-> {p "Bonjour tout le monde"}.call) == (-> {puts "Bonjour tout le monde".inspect}.call ) . De nombreux votes positifs NE font pas de cette réponse une bonne réponse!

5voto

fangxing Points 1771

De document ruby-2.4.1

puts

puts(obj, ...) → nil

Écrit l'objet (ou les objets) donné(s) dans ios. Écrit un retour à la ligne après ceux qui n'en comportent pas déjà. Retourne nil.

Le flux doit être ouvert en écriture. Si appelée avec un argument de type tableau, écrit chaque élément sur une nouvelle ligne. Chaque objet donné qui n'est pas une chaîne de caractères ou un tableau sera converti en appelant sa méthode to_s. Si appelée sans argument, affiche un seul retour à la ligne.

essayons sur irb

# toujours un retour à la ligne à la fin 
>> puts # pas d'arguments

=> nil # retourne nil et écrit un retour à la ligne
>> puts "sss\nsss\n" # retour à la ligne dans une chaîne de caractères
sss
sss
=> nil
>> puts "sss\nsss" # pas de retour à la ligne dans la chaîne
sss
sss
=> nil

# pour des arguments multiples et un tableau
>> puts "a", "b"
a
b
=> nil
>> puts "a", "b", ["c", "d"]
a
b
c
d
=> nil

p

p(obj) → obj cliquez pour basculer la source
p(obj1, obj2, ...) → [obj, ...] p() → nil
Pour chaque objet, écrit directement obj.inspect suivi d'un retour à la ligne dans la sortie standard du programme.

sur irb

# pas d'arguments
>> p
=> nil # retourne nil, n'écrit rien
# un argument
>> p "sss\nsss\n" 
"sss\nsss\n"
=> "aaa\naaa\n"
# arguments multiples et un tableau
>> p "a", "b"
"a"
"b"
=> ["a", "b"] # retourne un tableau
>> p "a", "b", ["c", "d"]
"a"
"b"
["c", "d"]
=> ["a", "b", ["c", "d"]] # retourne un tableau imbriqué

3voto

Jonathan_W Points 73

En plus des réponses ci-dessus, il existe une différence subtile dans la sortie de la console - à savoir la présence/l'absence de guillemets - qui peut être utile :

p "+++++"
>> "+++++"

puts "====="
>> =====

Je trouve cela utile si vous voulez créer une barre de progression simple, en utilisant leur proche parent print :

array = [beaucoup d'objets à traiter]
array.size
>> 20

Cela donne la barre de progression de 100 % :

puts "*" * array.size
>> ********************

Et cela ajoute un * incrémentiel à chaque itération :

array.each do |obj|
   print "*"
   obj.some_long_executing_process
end

# Cela s'incrémente joliment pour donner au développeur une indication de la progression / du temps restant avant l'achèvement
>> ******

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X