Czy jest jakaś różnica między Ruby pi pomiędzy nimi puts?
Czy jest jakaś różnica między Ruby pi pomiędzy nimi puts?
Odpowiedzi:
p foowypisuje foo.inspectznak nowej linii, tzn. wypisuje wartość inspectzamiast zamiast to_s, co jest bardziej odpowiednie do debugowania (ponieważ można np. odróżnić 1, "1"a od "2\b1"czego nie można drukować bez inspect).
pzwraca również wartość obiektu, podczas gdy putsnie. 1.9.3p125 :002 > (p "foo").class "foo" => String 1.9.3p125 :003 > (puts "foo").class foo => NilClass
to_sjest standardową metodą ciągów w języku Ruby. inspect. jak powiedziałem, jest alternatywą dla metody string, która daje wyjście bardziej odpowiednie do debugowania. Po zakończeniu debugowania powinieneś oczywiście usunąć instrukcje debugowania (lub w przypadku poważniejszych projektów prawdopodobnie powinieneś użyć struktury rejestrowania i nie używać p lub putów do debugowania w ogóle). Fakt, że obiekt jest pzwracany, wydaje się nieistotny w większości sytuacji (i sądzę, że udzieliłem tej odpowiedzi, zanim tak się stało). Różnica w wydajności jest główną różnicą (i kiedyś była jedyną).
Należy również zauważyć, że puts„reaguje” na to_szdefiniowaną klasę , pa nie. Na przykład:
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>
Wynika to bezpośrednio z .inspectpołączenia, ale w praktyce nie jest to oczywiste.
p foo jest taki sam jak puts foo.inspect
putszwraca nil, zamiast foojak robi p.
puts foo.inspect; foo
(-> {p "Hello World"}.call) == (-> {puts "Hello World".inspect}.call ) . Wiele głosów pozytywnych NIE czyni z tego dobrej odpowiedzi!
Oprócz powyższych odpowiedzi istnieje subtelna różnica w wynikach konsolowych - mianowicie obecność / brak odwróconych przecinków / cudzysłowów - które mogą być przydatne:
p "+++++"
>> "+++++"
puts "====="
>> =====
Uważam to za przydatne, jeśli chcesz zrobić prosty pasek postępu, używając ich bliskiego krewnego, wydrukuj :
array = [lots of objects to be processed]
array.size
>> 20
Daje to pasek postępu 100%:
puts "*" * array.size
>> ********************
A to dodaje przyrostowe * przy każdej iteracji:
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, ...) → nilZapisuje podane obiekty w systemie iOS. Zapisuje nowy wiersz po dowolnym, który jeszcze nie kończy się sekwencją nowego wiersza. Zwraca zero .
Strumień musi być otwarty do zapisu. Wywołany z argumentem tablicowym zapisuje każdy element w nowym wierszu. Każdy dany obiekt, który nie jest łańcuchem ani tablicą, zostanie przekonwertowany przez wywołanie jego
to_smetody. Wywołany bez argumentów, wyświetla pojedynczy znak nowej linii.
spróbujmy na 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
Dla każdego obiektu zapisuje bezpośrednio,obj.inspecta następnie nowy wiersz na standardowe wyjście programu.
w 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
Te 2 są równe:
p "Hello World"
puts "Hello World".inspect
( inspekcja daje bardziej dosłowny widok obiektu w porównaniu do metody to_s )
(->{p "Hello World"}.call) == (-> {puts "Hello World".inspect}.call )
Może to ilustrować jedną z kluczowych różnic, która polega na tym, że pzwraca wartość tego, co jest do niej przekazywane, gdzie putszwraca 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']
Testy porównawcze putssą wolniejsze
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)