p vs Ruby


270

Ruby'de pve putsRuby arasında herhangi bir fark var mı ?

Yanıtlar:


334

p foobaskılar foo.inspect, bir yeni satır ardından bu değerini yazar yani inspectyerine to_s(eğer örneğin arasındaki farkı nedeniyle ayıklama için daha uygundur, 1, "1"ve "2\b1"olmadan baskı yapmadığı zaman, hangi inspect).


7
Evet, p (ve koyarlar
mikej

17
Not pise de, nesnesinin değerini geri putsdeğildir. 1.9.3p125 :002 > (p "foo").class "foo" => String 1.9.3p125 :003 > (puts "foo").class foo => NilClass
Darren Cheng

2
Gareth Rees tarafından yayınlanan "Ruby p vs puts vs print" başlıklı yazı için özet .
alexanderjsingleton

Bu beni bir tavşan deliği soruları ile terk ediyor gibi hissediyorum. Ne inceliyor? Ne yapmalı? Değişken yerine yazdırılan metni neden incelemek istiyorum? Hata ayıklama, p veya koyarlardan bahsettiğiniz için programlama dünyası için hangisi daha standarttır? Hata ayıklama tamamlandıktan sonra tüm "p" yerine "koyar"? Yukarıdaki yorumda, p'nin büyük bir fark olan bir nesneyi döndürdüğünü görüyorum. Sadece orijinal soruya hala cevap veren daha büyük sorulara yol açacak küçük bir farktan bahsediyorsa, bu cevabın eksiksiz olup olmadığından emin değilim.

1
@AaronLoften to_s, Ruby'de standart dize yöntemidir. inspect. Dediğim gibi, hata ayıklama için daha uygun bir çıktı üreten bir dize yöntemidir. Hata ayıklamayı tamamladıktan sonra hata ayıklama ifadelerinizi açıkça kaldırmalısınız (veya daha ciddi projeler için muhtemelen bir günlük kaydı çerçevesi kullanmalı ve hata ayıklama için p veya puts kullanmamalısınız). pNesneyi döndüren gerçeği çoğu durumda ilgisiz görünüyor (ve bence bu cevabı durumdan önce verdim). Çıktıdaki fark ana farktır (ve eskiden tek olan).
sepp2k

54

Ayrıca, tanımlanmış putsbir sınıfa "tepki vermediğini " belirtmek de önemlidir . Örneğin:to_sp

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>

Bu doğrudan .inspectçağrıdan kaynaklanır, ancak pratikte açık değildir.


37

p foo aynıdır puts foo.inspect


4
ama putsdöner nil, yerine fooyaptığı gibi p.
ribamar

10
Bu yanlış. Aynı şeyputs foo.inspect; foo
Eric Duminil

Bu konum cevap yanlış size kanıtlıyor: (-> {p "Hello World"}.call) == (-> {puts "Hello World".inspect}.call ) . Birçok upvotes bunu iyi bir cevap DEĞİLDİR!
lacostenycoder

3

Yukarıdaki cevaplara ek olarak, konsol çıktısında ince bir fark vardır - yani, virgül / tırnak işaretlerinin varlığı / yokluğu - yararlı olabilir:

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

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

Basit bir ilerleme çubuğu yapmak istiyorsanız ben onların yakın akrabası kullanarak, bu yararlı bulmak, baskı :

array = [lots of objects to be processed]
array.size
>> 20

Bu% 100 ilerleme çubuğu verir:

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

Ve bu her yinelemeye artımlı * ekler:

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

2

Gönderen yakut-2.4.1 belgesinde

koyar

puts(obj, ...) → nil

Belirtilen nesneleri ios'a yazar. Önceden bir satırsonu dizisiyle bitmeyen herhangi bir satırdan sonra bir satırsonu yazar . Nil döndürür .

Akış yazmak için açılmalıdır. Dizi bağımsız değişkeniyle çağrılırsa , her öğeyi yeni bir satıra yazar . Dize veya dizi olmayan her bir nesne, to_s yöntemi çağrılarak dönüştürülür . Bağımsız değişken olmadan çağrılırsa, tek bir satırsonu verir.

hadi irb'de deneyelim

# 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
Her nesne için doğrudan obj.inspectprogramın standart çıktısına bir satırsonu yazar .

irb'de

# 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

0

Bu 2 eşittir:

p "Hello World"  
puts "Hello World".inspect

( inspect , nesnenin to_s yöntemine kıyasla daha gerçek bir görünümünü verir )


eşit görünüyorlar, ama DEĞİLDİR. Deneyin:(->{p "Hello World"}.call) == (-> {puts "Hello World".inspect}.call )
lacostenycoder

0

Bu, anahtar farklılıklardan birini gösterebilir, yani pkendisine iletilen değerin değerini döndürür, burada putsdöndürür 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']

Karşılaştırma göstergeleri putsdaha yavaş

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.