Feature #7654
open
Add optional code block to IO::readlines
Added by shock_one (Володимир Шацький) almost 12 years ago.
Updated 8 months ago.
Description
Of course, we always can write something like
File.readlines('/home/shock_one/test.rb').map{ |line| line.upcase }
but this way we create unneeded intermediate array which can be pretty big.
There is also a method IO::foreach, but it doesn't collect return values.
Besides it seems pretty logical and natural to have a block in this method.
Just to be clear: code block will allow to write the first code snippet as follows:
data = File.readlines('/home/shock_one/test.rb'){ |line| line.upcase }
Why not
File.foreach('test.rb').map { |line| line.upcase }
?
It does not create an intermediary Array.
If you need to do other operations lazily (without an intermediate result), you could use #lazy:
File.foreach('test.rb').lazy.select { |line| line.start_with? '/' }.map { |line| line.upcase }.to_a
But of course the main memory usage here are likely String instances, so you could update them in place if possible:
File.foreach('test.rb').map { |line| line.upcase!; line }
# or
lines = File.readlines('test.rb')
lines.each(&:upcase!)
(There is also Array#map!)
Thank you, Eregon, especially for in place methods. I should definitely pay more attention to them - functional languages made me a little suspicious of this sort of things.
But I still think it would be nice to have an optional block in IO::readlines, at least for convenience. Enumerable#grep has similar behavior and I find it really cool and useful. Also this change doesn't break anything, is easy to implement and makes the code more concise.
next minor issue or 2.0.0 issue?
I think next minor. It is a new feature but trunk is closed for new features.
- Target version set to 2.6
- Assignee set to matz (Yukihiro Matsumoto)
- Target version deleted (
2.6)
- Status changed from Open to Assigned
Also available in: Atom
PDF
Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0