¿Hay alguna diferencia entre py putsen Ruby?
¿Hay alguna diferencia entre py putsen Ruby?
Respuestas:
p fooimprime foo.inspectseguido de una nueva línea, es decir, imprime el valor de en inspectlugar de to_s, que es más adecuado para la depuración (porque, por ejemplo, puede distinguir la diferencia entre 1, "1"y "2\b1", que no puede imprimir sin inspect).
ptambién devuelve el valor del objeto, mientras putsque no. 1.9.3p125 :002 > (p "foo").class "foo" => String 1.9.3p125 :003 > (puts "foo").class foo => NilClass
to_ses el método estándar para encadenar en Ruby. inspect. Como dije, es un método alternativo para cadenas, que produce una salida más adecuada para la depuración. Una vez completada la depuración, obviamente debe eliminar sus declaraciones de depuración (o para proyectos más serios, probablemente debería usar un marco de registro y no usar p o put para la depuración). El hecho de que pdevuelva el objeto parece irrelevante en la mayoría de las situaciones (y creo que di esta respuesta antes de que este fuera el caso). La diferencia en la salida es la diferencia principal (y solía ser la única).
También es importante tener en cuenta que puts"reacciona" a una clase que ha to_sdefinido, pno lo hace. Por ejemplo:
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>
Esto se deduce directamente de la .inspectllamada, pero no es obvio en la práctica.
p foo es lo mismo que puts foo.inspect
putsregresa nil, en lugar de foocomo lo hace p.
puts foo.inspect; foo
(-> {p "Hello World"}.call) == (-> {puts "Hello World".inspect}.call ) . ¡Muchos votos positivos NO hacen que esta sea una buena respuesta!
Además de las respuestas anteriores, hay una sutil diferencia en la salida de la consola, es decir, la presencia / ausencia de comillas / comillas invertidas, que puede ser útil:
p "+++++"
>> "+++++"
puts "====="
>> =====
Encuentro esto útil si desea hacer una barra de progreso simple, utilizando su pariente cercano, imprimir :
array = [lots of objects to be processed]
array.size
>> 20
Esto da la barra de progreso del 100%:
puts "*" * array.size
>> ********************
Y esto agrega un * incremental en cada iteración:
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, ...) → nilEscribe los objetos dados en ios. Escribe una nueva línea después de cualquiera que aún no termine con una secuencia de nueva línea. Devuelve nulo .
La secuencia debe estar abierta para escritura. Si se llama con un argumento de matriz , escribe cada elemento en una nueva línea. Cada objeto dado que no sea una cadena o matriz se convertirá llamando a su
to_smétodo. Si se llama sin argumentos, genera una nueva línea nueva.
probémoslo en 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
Para cada objeto, escribe directamenteobj.inspectseguido de una nueva línea en la salida estándar del programa.
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
Estos 2 son iguales:
p "Hello World"
puts "Hello World".inspect
( inspeccionar ofrece una vista más literal del objeto en comparación con el método to_s )
(->{p "Hello World"}.call) == (-> {puts "Hello World".inspect}.call )
Esto puede ilustrar una de las diferencias clave, que es que pdevuelve el valor de lo que se le pasa, donde se putsdevuelve 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']
Los programas de referencia putsson más lentos
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)