From 59eb99bcb849ad75f8715f5dbd56059943d66a69 Mon Sep 17 00:00:00 2001 From: Ian Katz Date: Sat, 25 Jan 2020 00:09:29 -0500 Subject: [PATCH] Add each_line enumerator to IO class --- lib/piperator/io.rb | 7 +++++++ spec/piperator/io_spec.rb | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/lib/piperator/io.rb b/lib/piperator/io.rb index abb8ff1..2bc0429 100644 --- a/lib/piperator/io.rb +++ b/lib/piperator/io.rb @@ -49,6 +49,13 @@ def gets(separator = $INPUT_RECORD_SEPARATOR, _limit = nil) read_with { @buffer.gets(separator) } end + # Returns an enumerator of lines in the stream, without reading the entire stream into memory + # + # @return [Enumerator] + def each_line + Enumerator.new { |y| loop { y << gets&.gsub(/#{$INPUT_RECORD_SEPARATOR}$/, '') } }.lazy.take_while(&:itself).each + end + # Flush internal buffer until the last unread byte def flush if @buffer.pos == @buffer_read_pos diff --git a/spec/piperator/io_spec.rb b/spec/piperator/io_spec.rb index 247a0dc..1770ffc 100644 --- a/spec/piperator/io_spec.rb +++ b/spec/piperator/io_spec.rb @@ -81,6 +81,14 @@ end end + describe '#each_line' do + subject { Piperator::IO.new(["foo\n", "bar\n", "baz\nbmp"].each) } + + it 'return enumerated lines' do + expect(subject.each_line.to_a).to eq(["foo", "bar", "baz", "bmp"]) + end + end + describe '#flush' do subject { Piperator::IO.new(['a' * 16 * KILOBYTE].each) } let(:flush_threshold) { Piperator::IO::FLUSH_THRESHOLD }