【发布时间】:2012-09-17 12:26:41
【问题描述】:
什么时候使用 Ruby 的 StringIO 而不是只使用 String 才是合适的?
我想我理解它们之间的根本区别,正如“What is ruby's StringIO class really?”所强调的那样,StringIO 使人们能够以面向流的方式读取/写入字符串。但这实际上意味着什么?
当简单地使用 String 并不能真正削减它时,使用 StringIO 的实际用途的一个很好的例子是什么?
【问题讨论】:
什么时候使用 Ruby 的 StringIO 而不是只使用 String 才是合适的?
我想我理解它们之间的根本区别,正如“What is ruby's StringIO class really?”所强调的那样,StringIO 使人们能够以面向流的方式读取/写入字符串。但这实际上意味着什么?
当简单地使用 String 并不能真正削减它时,使用 StringIO 的实际用途的一个很好的例子是什么?
【问题讨论】:
基本上,它使字符串看起来像一个 IO 对象,因此命名为 StringIO。
StringIO 类具有 read 和 write 方法,因此可以将其传递给设计用于从文件或套接字读取和写入的代码部分。如果你有一个字符串并且你希望它看起来像一个文件来测试你的文件代码,那就太好了。
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
【讨论】:
StringIO 并没有内存优势,但如果您为 IO 对象设计函数,您可以执行诸如从文件读取之类的操作,或者一起进行管道操作。因此,如果与适当的类一起使用,则采用 IO 对象的函数可以使用更少的内存。因此,这使您可以以相同的方式对 String 或可能更高效的 IO 对象进行操作。
StringIO 与File 的外观完全相同。我刚刚遇到的一个“问题”——File.size(StringIO.new('foo')) #=> TypeError: no implicit conversion of StringIO into String
我真的很喜欢 StringIO 用于逐行附加文本的用例,而不必一遍又一遍地使用"\n"。例如,而不是这个:
s = ''
s << "\n" << "some text on a new line"
s << "\nthis is pretty awkward"
s = "#{s}\neven more ugly!"
我能做到
s = StringIO.open do |s|
s.puts 'adding newlines with puts is easy...'
s.puts 'and simple'
s.string
end
这更清洁。不必使用String.IO 的块形式,您可以像这样创建一个对象:s = StringIO.new 但无论如何,请务必记住实际字符串是通过StringIO#string 方法访问的。
【讨论】:
Array#<< 然后Array#join 来处理这种事情,尽管使用StringIO 是一种很棒的技术。
Array 就像你描述的那样当然,写入很方便,但是当读取代码时,类名StringIO是一个远更好的目的指标。更不用说Array 是一个根本不同的数据结构。此外,使用Array#join 的必要性会导致过多的代码“包袱”,更糟糕的是,复杂性!例如,它的参数默认设置为全局变量。