Y a-t-il une différence entre pet putsen Ruby?
Y a-t-il une différence entre pet putsen Ruby?
Réponses:
p fooimprime foo.inspectsuivi d'une nouvelle ligne, c'est-à-dire qu'il imprime la valeur de inspectau lieu de to_s, ce qui est plus approprié pour le débogage (parce que vous pouvez par exemple faire la différence entre 1, "1"et "2\b1", ce que vous ne pouvez pas lorsque vous imprimez sans inspect).
prenvoie également la valeur de l'objet, alors putsque non. 1.9.3p125 :002 > (p "foo").class "foo" => String 1.9.3p125 :003 > (puts "foo").class foo => NilClass
to_sest la méthode standard de chaîne dans Ruby. inspect. comme je l'ai dit, est une méthode alternative à la chaîne, qui produit une sortie plus adaptée au débogage. À la fin du débogage, vous devez évidemment supprimer vos instructions de débogage (ou pour des projets plus sérieux, vous devriez probablement utiliser un cadre de journalisation et ne pas utiliser du tout p ou put pour le débogage). Le fait que pretourne l'objet semble hors de propos dans la plupart des situations (et je crois avoir donné cette réponse avant que ce soit le cas). La différence de sortie est la principale différence (et était la seule).
Il est également important de noter que puts"réagit" à une classe qui l'a to_sdéfinie, pne 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' .inspectappel, mais n'est pas évident en pratique.
p foo est le même que puts foo.inspect
putsrevient nil, au lieu de foole faire p.
puts foo.inspect; foo
(-> {p "Hello World"}.call) == (-> {puts "Hello World".inspect}.call ) . Beaucoup de votes positifs n'en font PAS une bonne réponse!
En plus des réponses ci-dessus, il existe une différence subtile dans la sortie de la console - à savoir la présence / absence de virgules / guillemets inversés - qui peut être utile:
p "+++++"
>> "+++++"
puts "====="
>> =====
Je trouve cela utile si vous voulez faire une barre de progression simple, en utilisant leur proche parent, imprimez :
array = [lots of objects to be processed]
array.size
>> 20
Cela donne la barre de progression à 100%:
puts "*" * array.size
>> ********************
Et cela ajoute un incrémental * à 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
>> ******
puts(obj, ...) → nilÉcrit le ou les objets donnés dans ios. Écrit une nouvelle ligne après une séquence qui ne se termine pas déjà par une séquence de nouvelle ligne. Renvoie nil .
Le flux doit être ouvert pour l'écriture. S'il est appelé avec un argument tableau , é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
to_sméthode. S'il est appelé sans arguments, génère une seule nouvelle ligne.
essayons 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(obj) → obj click to toggle source
p(obj1, obj2, ...) → [obj, ...]p() → nil
Pour chaque objet, écrit directementobj.inspectsuivi d'un retour à la sortie standard du programme.
en 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
Ces 2 sont égaux:
p "Hello World"
puts "Hello World".inspect
( inspect donne une vue plus littérale de l'objet par rapport à la méthode to_s )
(->{p "Hello World"}.call) == (-> {puts "Hello World".inspect}.call )
Cela peut illustrer l'une des principales différences qui est celle qui prenvoie la valeur de ce qui lui est transmis, où en tant que putsretour 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']
L'indice de référence putsest plus lent
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)