ruby cookbook -- Enumerable mixin - good example of Ruby's duck typing

Similarly, File and String both include the Enumerable mixin, so in a lot of cases you can read from an object without caring what type it is. This is a good example of Ruby's duck typing.

#Here's a string:
poem = %{The boy stood on the burning deck
Whence all but he had fled
He'd stayed above to wash his neck
Before he went to bed}
#and a file containing that string:

output = open("poem", "w")
output.write(poem)
output.close
input = open("poem")
#will give the same result when you call an Enumerable method:
poem.grep /ed$/
# => ["Whence all but he had fled\n", "Before he went to bed"]
input.grep /ed$/
# => ["Whence all but he had fled\n", "Before he went to bed"]


Just remember that, unlike a string, you can't iterate over a file multiple times without calling rewind:

input.grep /ed$/ # => []
input.rewind
input.grep /ed$/
# => ["Whence all but he had fled\n", "Before he went to bed"]


StringIO comes in when the Enumerable methods and << aren't enough. If a method you're writing needs to use methods specific to IO, you can accept a string as input and wrap it in a StringIO. The class also comes in handy when you need to call a method someone else wrote, not anticipating that anyone would ever need to call it with anything other than a file:

def fifth_byte(file)
file.seek(5)
file.read(1)
end

fifth_byte("123456")
# NoMethodError: undefined method `seek' for "123456":String
fifth_byte(StringIO.new("123456")) # => "6"


When you write a method that accepts a file as an argument, you can silently accommodate callers who pass in strings by wrapping in a StringIO any string that gets passed in:

def file_operation(io)
io =
StringIO(io) if io.respond_to? :to_str && !io.is_a? StringIO
#Do the file operation…
end


A StringIO object is always open for both reading and writing:

s = StringIO.new
s << "A string"
s.read # => ""
s << ", and more."
s.rewind
s.read # => "A string, and more."


Memory access is faster than disk access, but for large amounts of data (more than about 10 kilobytes), StringIO objects are slower than disk files. If speed is your aim, your best bet is to write to and read from temp files using the tempfile module. Or you can do what the open-uri library does: start off by writing to a StringIO and, if it gets too big, switch to using a temp file.
内存访问速度比磁盘要会,但是对于大量数据,stringio对象要比磁盘文件要慢。比较好的方法是使用tempfile模板写入并从临时文件中读出。可以想open-uri库那样,开始用stringio,如果数据过大,在使用tempfile。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值