2009-08-10 6 views

Antwort

286

p foo druckt foo.inspect durch eine neue Zeile gefolgt, dh er den Wert von inspect statt to_s druckt, die für das Debuggen besser geeignet ist (weil Sie zB den Unterschied zwischen 1, "1" und "2\b1", sagen kann, das kann man nicht, wenn Drucken ohne inspect).

+7

Yep, p (und Puts) sind sowohl im Kernel-Modul So können Sie die Details hier sehen: http://www.ruby-doc.org/core/classes/Kernel.html#M005961 – mikej

+11

Beachten Sie, dass 'p' auch den Wert des Objekts zurückgibt, während' puts' dies nicht tut. '1.9.3p125: 002> (p" foo "). Klasse" foo "=> String 1.9.3p125: 003> (puts" foo "). Klasse foo => NilClass' –

+2

Große Zusammenfassung zur Verfügung gestellt von Gareth Rees in seinem Beitrag mit dem Titel ["Ruby p vs puts vs print"] (http://www.garethrees.co.uk/05/05/04/p-vs-puts-vs-print-in-ruby/). – alexanderjsingleton

36

p foo ist die gleiche wie puts foo.inspect

+3

aber 'puts' gibt' nil' zurück, anstatt 'foo' wie' p'. – ribamar

+5

Das ist falsch. Es ist das gleiche wie 'puts foo.inspect; foo' –

51

Es ist auch wichtig, dass puts „reagiert“ auf eine Klasse zu beachten, dass to_s definiert hat, tut p nicht. Zum Beispiel:

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> 

Dies folgt unmittelbar aus dem .inspect Ruf, ist aber in der Praxis nicht auf der Hand.

1

Von ruby-2.4.1 document

setzt

puts(obj, ...) → nil

das angegebene Objekt Schreibt (en) auf ios. Schreibt einen Newline nach irgendeinem do nicht bereits Ende mit einer Newline-Sequenz. Gibt null zurück.

Der Stream muss zum Schreiben geöffnet werden. Wenn mit einem Array Argument aufgerufen wird, schreibt jedes Element auf einer neuen Zeile. Jedes gegebene Objekt , das keine Zeichenfolge oder kein Array ist, wird konvertiert, indem seine Methode to_s aufgerufen wird. Wenn sie ohne Argumente aufgerufen wird, wird ein einzelner Zeilenumbruch ausgegeben.

versuchen wir es auf 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
Für jedes Objekt wird direkt obj.inspect gefolgt von einem Zeilenumbruch an die Standardausgabe des Programms geschrieben.

in 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

Zusätzlich zu den oben genannten Antworten gibt es einen feinen Unterschied in der Konsolenausgabe - nämlich das Vorhandensein/Fehlen von Anführungszeichen/Anführungszeichen - die nützlich sein können:

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

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

ich finde diese nützlich, wenn Sie eine einfache Fortschrittsbalken machen wollen, die ihre engen Verwandten mit, Druck:

Dies gibt die 100% Fortschrittsbalken:

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

Davon profitiert eine inkrementelle * auf jede Iteration:

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