C'è qualche differenza tra pe putsin Ruby?
C'è qualche differenza tra pe putsin Ruby?
Risposte:
p foostampe foo.inspectseguite da una nuova riga, ovvero stampa il valore di inspectinvece di to_s, che è più adatto per il debug (perché puoi ad esempio dire la differenza tra 1, "1"e "2\b1", che non puoi quando stampi senza inspect).
prestituisce anche il valore dell'oggetto, mentre putsnon lo fa. 1.9.3p125 :002 > (p "foo").class "foo" => String 1.9.3p125 :003 > (puts "foo").class foo => NilClass
to_sè il metodo standard a stringa in Ruby. inspect. come ho detto, è un metodo alternativo alla stringa, che produce un output più adatto per il debug. Al termine del debug è necessario rimuovere ovviamente le dichiarazioni di debug (o per progetti più seri è consigliabile utilizzare un framework di registrazione e non utilizzare p o put per il debug). Il fatto che prestituisca l'oggetto sembra irrilevante nella maggior parte delle situazioni (e credo di aver dato questa risposta prima che questo fosse il caso). La differenza nell'output è la differenza principale (ed era l'unica).
È anche importante notare che puts"reagisce" a una classe che ha to_sdefinito, pno. Per esempio:
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>
Ciò deriva direttamente dalla .inspectchiamata, ma non è ovvio in pratica.
p foo equivale a puts foo.inspect
putsritorna nil, invece di foocome fa p.
puts foo.inspect; foo
(-> {p "Hello World"}.call) == (-> {puts "Hello World".inspect}.call ) . Molti voti NON ne fanno una buona risposta!
Oltre alle risposte di cui sopra, esiste una sottile differenza nell'output della console - vale a dire la presenza / assenza di virgole / virgolette invertite - che può essere utile:
p "+++++"
>> "+++++"
puts "====="
>> =====
Lo trovo utile se vuoi creare una semplice barra di avanzamento, usando il loro parente stretto, stampa :
array = [lots of objects to be processed]
array.size
>> 20
Questo dà la barra di avanzamento del 100%:
puts "*" * array.size
>> ********************
E questo aggiunge un * incrementale su ogni iterazione:
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
>> ******
A partire dal documento ruby-2.4.1
puts(obj, ...) → nilScrive gli oggetti dati su iOS. Scrive una nuova riga dopo quella che non termina già con una sequenza di nuova riga. Restituisce zero .
Lo stream deve essere aperto per la scrittura. Se chiamato con un argomento array , scrive ogni elemento su una nuova riga. Ogni dato oggetto che non è una stringa o un array verrà convertito chiamando il suo
to_smetodo. Se chiamato senza argomenti, genera una nuova riga.
proviamo su 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(obj) → obj click to toggle source
p(obj1, obj2, ...) → [obj, ...]p() → nil
Per ogni oggetto, scrive direttamenteobj.inspectseguito da una nuova riga nell'output standard del programma.
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
Questi 2 sono uguali:
p "Hello World"
puts "Hello World".inspect
( inspect offre una visione più letterale dell'oggetto rispetto al metodo to_s )
(->{p "Hello World"}.call) == (-> {puts "Hello World".inspect}.call )
Questo può illustrare una delle differenze chiave che è che prestituisce il valore di ciò che gli viene passato, dove come putsritorna nil.
def foo_puts
arr = ['foo', 'bar']
puts arr
end
def foo_p
arr = ['foo', 'bar']
p arr
end
a = foo_puts
=>nil
a
=>nil
b = foo_p
=>['foo', 'bar']
b
['foo', 'bar']
Gli spettacoli di benchmark sono putspiù lenti
require 'benchmark'
str = [*'a'..'z']
str = str*100
res = Benchmark.bm do |x|
x.report(:a) { 10.times {p str} }
x.report(:b) { 10.times {puts str} }
end
puts "#{"\n"*10}"
puts res
0.010000 0.000000 0.010000 ( 0.047310)
0.140000 0.090000 0.230000 ( 0.318393)