2009-08-10 6 views

Répondre

286

p foo estampes foo.inspect suivie par une nouvelle ligne, soit il imprime la valeur de inspect au lieu de to_s, qui est plus approprié pour le débogage (parce que vous pouvez par exemple faire la différence entre 1, "1" et "2\b1", que vous ne pouvez pas quand impression sans inspect).

+7

Yep, p (et met) sont à la fois dans le module du noyau donc vous pouvez voir les détails ici: http://www.ruby-doc.org/core/classes/Kernel.html#M005961 – mikej

+11

Notez que 'p' renvoie aussi la valeur de l'objet, alors que' puts' ne le fait pas. '1.9.3p125: 002> (p" foo "). Classe" foo "=> Chaîne 1.9.3p125: 003> (met" foo "). Classe foo => NilClass' –

+2

Grand résumé fourni par Gareth Rees dans son article intitulé ["Ruby p vs puts vs print"] (http://www.garethrees.co.uk/2013/05/04/p-vs-puts-vs-print-in-ruby/). – alexanderjsingleton

36

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

+3

mais 'puts' renvoie' nil', au lieu de 'foo' comme le fait' p'. – ribamar

+5

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

51

Il est également important de noter que puts « réagisse » à une classe qui a défini to_s, p ne fonctionne 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 évidente dans la pratique.

1

De ruby-2.4.1 document

met

puts(obj, ...) → nil

écrit l'objet donné (s) à ios. Écrit un newline après tout ce faire pas déjà fin avec une séquence de nouvelle ligne. Renvoie zéro.

Le flux doit être ouvert pour l'écriture. Si appelé avec un tableau argument, écrit chaque élément sur une nouvelle ligne. Chaque objet donné qui n'est pas une chaîne ou un tableau sera converti en appelant sa méthode to_s . S'il est appelé sans arguments, génère un seul saut de ligne.

nous allons essayer sur 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

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

dans irb

# 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 
1

En plus des réponses ci-dessus, il y a une différence subtile en sortie de la console - à savoir la présence/absence de marques virgules/guillemets inversées - qui peut être utile:

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

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

Je trouve cela utile si vous souhaitez effectuer une simple barre de progression, en utilisant le leur proche parent, impression:

array = [lots of objects to be processed] 
array.size 
>> 20 

Cela donne à la barre de progression de 100%:

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

Et cela ajoute une supplémentaire * à chaque itération:

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 
>> ******