Class: ProgressiveIO

Inherits:
SimpleDelegator
  • Object
show all
Defined in:
lib/progressive_io.rb

Overview

A wrapper class that provides progress tracking for IO operations.

This class wraps an IO object and calls a progress block whenever data is read, allowing you to track reading progress for operations like file uploads or downloads.

Examples:

Basic usage with a file

file = File.open('large_file.txt')
progress_io = ProgressiveIO.new(file) do |current_pos|
  puts "Read #{current_pos} bytes"
end

progress_io.each_line do |line|
  # Process each line
end

Usage with a StringIO

string_io = StringIO.new("Hello\nWorld\n")
progress_io = ProgressiveIO.new(string_io) do |current_pos|
  puts "Read #{current_pos} bytes"
end

content = progress_io.read

Since:

  • 2.0.0

Constant Summary collapse

VERSION =

The version of the ProgressiveIO library

Since:

  • 2.0.0

'2.0.2'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(with_io, &blk) {|current_pos| ... } ⇒ ProgressiveIO

Creates a new ProgressiveIO wrapper around an IO object.

Examples:

file = File.open('data.txt')
progress_io = ProgressiveIO.new(file) do |pos|
  puts "Read #{pos} bytes"
end

Parameters:

  • with_io (IO)

    The IO object to wrap (File, StringIO, etc.)

  • blk (Proc, nil)

    Optional block that will be called when data is read The block receives one parameter: current position

Yields:

  • (current_pos)

    The progress callback

Yield Parameters:

  • current_pos (Integer)

    The current position in the IO stream

Since:

  • 2.0.0



50
51
52
53
# File 'lib/progressive_io.rb', line 50

def initialize(with_io, &blk)
  super(with_io)
  @progress_block = blk.to_proc if blk
end

Instance Attribute Details

#progress_blockProc?

Returns The progress callback block that will be called when data is read The block receives one parameter: current position.

Returns:

  • (Proc, nil)

    The progress callback block that will be called when data is read The block receives one parameter: current position

Since:

  • 2.0.0



35
36
37
# File 'lib/progressive_io.rb', line 35

def progress_block
  @progress_block
end

Instance Method Details

#each(*args) {|line| ... } ⇒ Enumerator

Iterates over the IO stream line by line, calling the progress block for each line.

Examples:

progress_io.each do |line|
  puts "Processing: #{line.chomp}"
end

Using as an Enumerator

progress_io.each.with_index do |line, idx|
  puts "Line #{idx}: #{line.chomp}"
end

Parameters:

  • args (Array)

    Arguments to pass to the underlying IO#each method (separator and/or limit)

Yields:

  • (line)

    Each line from the IO stream

Yield Parameters:

  • line (String)

    A line from the IO stream

Returns:

  • (Enumerator)

    An enumerator if no block is given

Since:

  • 2.0.0



71
72
73
74
75
76
77
78
# File 'lib/progressive_io.rb', line 71

def each(*args, &blk)
  return enum_for(__method__, *args) unless block_given?
  
  # Report offset at each call of the iterator
  super(*args) do |line|
    yield(line).tap { notify_read }
  end
end

#each_byte {|byte| ... } ⇒ Enumerator

Iterates over the IO stream byte by byte, calling the progress block for each byte.

Examples:

progress_io.each_byte do |byte|
  puts "Byte: #{byte}"
end

Using as an Enumerator

progress_io.each_byte.with_index do |byte, idx|
  puts "Byte #{idx}: #{byte}"
end

Yields:

  • (byte)

    Each byte from the IO stream

Yield Parameters:

  • byte (Integer)

    A byte from the IO stream (0-255)

Returns:

  • (Enumerator)

    An enumerator if no block is given

Since:

  • 2.0.0



118
119
120
121
122
123
# File 'lib/progressive_io.rb', line 118

def each_byte(&blk)
  return enum_for(__method__) unless block_given?
  
  # Report offset at each call of the iterator
  super { |b| yield(b).tap { notify_read } }
end

#each_line(*args) {|line| ... } ⇒ Enumerator

Iterates over the IO stream line by line, calling the progress block for each line. This is an alias-like method for #each that ensures proper Enumerator behavior.

Examples:

progress_io.each_line do |line|
  puts "Processing: #{line.chomp}"
end

Using as an Enumerator

progress_io.each_line.with_index do |line, idx|
  puts "Line #{idx}: #{line.chomp}"
end

Parameters:

  • args (Array)

    Arguments to pass to the underlying IO#each_line method (separator and/or limit)

Yields:

  • (line)

    Each line from the IO stream

Yield Parameters:

  • line (String)

    A line from the IO stream

Returns:

  • (Enumerator)

    An enumerator if no block is given

Since:

  • 2.0.0



97
98
99
100
101
# File 'lib/progressive_io.rb', line 97

def each_line(*args, &blk)
  return enum_for(__method__, *args) unless block_given?
  
  each(*args, &blk)
end

#getcString?

Reads a single character from the IO stream.

Returns:

  • (String, nil)

    The next character or nil if at end of stream

See Also:

  • IO#getc

Since:

  • 2.0.0



129
130
131
# File 'lib/progressive_io.rb', line 129

def getc
  super.tap { notify_read }
end

#gets(*args) ⇒ String?

Reads a line from the IO stream.

Parameters:

  • args (Array)

    Arguments to pass to the underlying IO#gets method

Returns:

  • (String, nil)

    The next line or nil if at end of stream

See Also:

  • IO#gets

Since:

  • 2.0.0



138
139
140
# File 'lib/progressive_io.rb', line 138

def gets(*args)
  super(*args).tap { notify_read }
end

#pos=(p) ⇒ Integer

Sets the position in the IO stream.

Parameters:

  • p (Integer)

    The new position

Returns:

  • (Integer)

    The new position

See Also:

  • IO#pos=

Since:

  • 2.0.0



206
207
208
# File 'lib/progressive_io.rb', line 206

def pos=(p)
  super(p).tap { notify_read }
end

#read(*a) ⇒ String?

Reads data from the IO stream.

Parameters:

  • a (Array)

    Arguments to pass to the underlying IO#read method

Returns:

  • (String, nil)

    The read data or nil if at end of stream

See Also:

  • IO#read

Since:

  • 2.0.0



147
148
149
# File 'lib/progressive_io.rb', line 147

def read(*a)
  super(*a).tap { notify_read }
end

#readbytes(*a) ⇒ String

Reads a specific number of bytes from the IO stream.

Parameters:

  • a (Array)

    Arguments to pass to the underlying IO#readbytes method

Returns:

  • (String)

    The read bytes

See Also:

  • IO#readbytes

Since:

  • 2.0.0



156
157
158
# File 'lib/progressive_io.rb', line 156

def readbytes(*a)
  super(*a).tap { notify_read }
end

#readcharString

Reads a single character from the IO stream.

Returns:

  • (String)

    The next character

Raises:

  • (EOFError)

    If at end of stream

See Also:

  • IO#readchar

Since:

  • 2.0.0



165
166
167
# File 'lib/progressive_io.rb', line 165

def readchar
  super.tap { notify_read }
end

#readline(*a) ⇒ String

Reads a line from the IO stream.

Parameters:

  • a (Array)

    Arguments to pass to the underlying IO#readline method

Returns:

  • (String)

    The next line

Raises:

  • (EOFError)

    If at end of stream

See Also:

  • IO#readline

Since:

  • 2.0.0



175
176
177
# File 'lib/progressive_io.rb', line 175

def readline(*a)
  super(*a).tap { notify_read }
end

#readlines(*a) ⇒ Array<String>

Reads all lines from the IO stream.

Parameters:

  • a (Array)

    Arguments to pass to the underlying IO#readlines method

Returns:

  • (Array<String>)

    Array of lines

See Also:

  • IO#readlines

Since:

  • 2.0.0



184
185
186
# File 'lib/progressive_io.rb', line 184

def readlines(*a)
  super(*a).tap { notify_read }
end

#seek(*a) ⇒ Integer

Seeks to a position in the IO stream.

Parameters:

  • a (Array)

    Arguments to pass to the underlying IO#seek method

Returns:

  • (Integer)

    The new position

See Also:

  • IO#seek

Since:

  • 2.0.0



193
194
195
# File 'lib/progressive_io.rb', line 193

def seek(*a)
  super(*a)
end