2012-09-25 13 views
36

Sadece String kullanmak yerine, Ruby's StringIO'yu kullanmak uygun olarak düşünülüyor mu?StringIO'nun String'e karşı olarak Stringio kullanmanın avantajları nelerdir?

"What is ruby's StringIO class really?" ile vurgulananlar arasındaki temel farkı anlıyorum ve StringIO'nun bir dize akış yönelimli bir şekilde okuma/yazma yapabilmesini sağladığını düşünüyorum. Ama bu pratik olarak ne anlama geliyor?

Sadece String kullanıldığında StringIO kullanıldığında pratik kullanım için iyi bir örnek nedir?

cevap

59

Temel olarak, bir dize bir IO nesnesine, dolayısıyla StringIO adına benziyor.

StringIO sınıfı, read ve write sınıf yöntemlerine sahiptir, bu nedenle kodunuzun dosyalara veya soketlere okunması ve yazılması için tasarlanmış bölümlerine geçirilebilir. Bir stringiniz varsa ve dosya kodunuzu test etmek amacıyla bir dosyaya benzetilmesini istiyorsanız hoş olur.

def foo_writer(file) 
    file.write "foo" 
end 

def test_foo_writer 
    s = StringIO.new 
    foo_writer(s) 
    raise "fail" unless s.string == "foo" 
end 
+3

İlginç. StringIO’yu String’e karşı kullanırken (bellek kullanımıyla ilgili) herhangi bir avantaj var mıdır? –

+3

Muhtemelen değil. Kaynak koduna bakarsanız, dahili olarak bir String nesnesine bir başvuru tutar gibi görünür, bu yüzden normal bir dizeden biraz daha fazla bellek kullanır: https://github.com/ruby/ruby/blob/trunk/ext /stringio/stringio.c –

+2

Eğer 'StringIO' kullanıyorsanız, bir bellek avantajı olmasa da, IO nesneleri için fonksiyonlarınızı tasarlarsanız, bir dosyadan okunabilir ve başka bir şekilde boru işlemlerini bir arada yapabilirsiniz. Dolayısıyla, bir IO nesnesini alan bir işlev, uygun bir sınıfla kullanıldığında daha az bellek kullanabilir. Böylece, bu bir String veya daha verimli bir IO nesnesinde aynı şekilde çalışmanıza izin verir. –

23

Gerçekten tekrar tekrar "\n" kullanmak zorunda kalmadan metin satırını-by-line ekleme kullanımı-durum için StringIO gibi. Yerine bu Örneğin:

s = '' 
s << "\n" << "some text on a new line" 
s << "\nthis is pretty awkward" 
s = "#{s}\neven more ugly!" 

Ben daha temiz hangisi bu

s = StringIO.open do |s| 
    s.puts 'adding newlines with puts is easy...' 
    s.puts 'and simple' 
    s.string 
end 

yapabilirsiniz. String.IO blok biçimini kullanmak gerekli değildir, böyle bir nesneyi oluşturabilirsiniz: s = StringIO.new Ancak, bağımsız dizeye StringIO#string yöntemiyle erişildiğinden emin olun.

+1

'a çevirmem. Genellikle' Array # << 've sonra' 'kullanıyorum StringIO kullanmanın harika bir teknik olmasına rağmen, bu tür şeyler için # join 'dizisi. – jc00ke

+2

@ jc00ke Aslında ben yaptım. Şimdi Ruby ile daha aşina olduğuma göre, alışkanlıklarım ** okuyucuyu tercih eden bir kodla sonuçlandı. ** Ne demek istediğimi hatırlatmak için aşağıdakileri düşünün: Kodlayıcıya, 'Array' ifadesini kullanarak açıkla * yaz *, emin, ama * okuma * kodu, 'StringIO' sınıf adı ** ** daha iyi bir amaç göstergesidir. 'Array' demek, temelde farklı bir veri yapısıdır. Ayrıca, 'Array # join' kullanma zorunluluğu fazla kod 'bagaj' ve daha kötüsü karmaşıklık gerektirir! Örneğin, argüman varsayılan olarak değişime tabi olan bir global olarak ayarlanır. –

İlgili konular