2012-09-25 8 views
36

Quando si considera corretto utilizzare Stringy di Ruby anziché utilizzare semplicemente String?Quali sono i vantaggi dell'uso di StringIO in Ruby rispetto a String?

Penso di capire la differenza fondamentale tra di loro come evidenziato da "What is ruby's StringIO class really?", che StringIO consente di leggere e scrivere da/a una stringa in modo orientato al flusso. Ma cosa significa questo praticamente?

Quale è un buon esempio di utilizzo pratico per l'utilizzo di StringIO quando semplicemente l'uso di String non lo taglia davvero?

risposta

59

Fondamentalmente, assomiglia a una stringa come un oggetto IO, da cui il nome StringIO.

La classe StringIO ha i metodi read e write, quindi può essere passata a parti del codice che sono state progettate per leggere e scrivere da file o socket. È bello se si dispone di una stringa e si desidera che assomigli a un file ai fini della verifica del codice del file.

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

Interessante. Ci sono dei vantaggi (per quanto riguarda l'utilizzo della memoria) nell'uso di StringIO anziché di String? –

+3

Probabilmente no. Se si guarda il codice sorgente sembra che mantenga un riferimento ad un oggetto String internamente, quindi userà un po 'più di memoria di una stringa normale: https://github.com/ruby/ruby/blob/trunk/ext /stringio/stringio.c –

+2

Anche se non si dispone di un vantaggio di memoria se si utilizza 'StringIO', se si progettano le funzioni per oggetti IO, è possibile eseguire operazioni come leggere da un file e, altrimenti, eseguire operazioni di pipe. Quindi una funzione che accetta un oggetto IO può utilizzare meno memoria se viene utilizzata con una classe appropriata. Quindi, questo ti consente di operare su una stringa o su un oggetto IO possibilmente più efficiente allo stesso modo. –

23

Mi piace molto StringIO per il caso d'uso di aggiungendo linea per linea di testo senza dover utilizzare "\n" più e più volte. Per esempio, invece di questo:

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

posso fare questo

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

Che è molto più pulito. Non è necessario utilizzare il modulo di blocco di String.IO, è possibile creare un oggetto come questo: s = StringIO.new ma, a prescindere, assicurarsi di tenere presente che la stringa effettiva è accessibile tramite il metodo StringIO#string.

+1

Io di solito uso' Array # << 'e quindi' Array # join' per questo genere di cose, anche se l'uso di 'StringIO' è una tecnica eccezionale. – jc00ke

+2

@ jc00ke Così ho fatto davvero. Ora che ho più familiarità con Ruby, le mie abitudini si traducono in codice che favorisce il ** reader ** ... Per ignorare ciò che intendo, considera quanto segue: Per il coder, usare 'Array' come descrivi è comodo per * scrivi * in, certo, ma quando * legge * il codice, il nome della classe 'StringIO' è un indicatore ** di gran lunga migliore dello scopo. Per non parlare di 'Array' è una struttura di dati fondamentalmente diversa. Inoltre, l'importanza dell'uso di "Array # join" comporta l'eccesso di codice "bagaglio" e, peggio, la complessità! Ad esempio, l'argomento è impostato per impostazione predefinita su un valore globale che è soggetto a modifiche. –

Problemi correlati