Class: Alf::Reader

Inherits:
Object
  • Object
show all
Extended by:
Support::Registry
Includes:
Engine::Cog, Enumerable
Defined in:
lib/alf-io/alf/reader.rb,
lib/alf-io/alf/reader/csv.rb,
lib/alf-io/alf/reader/json.rb,
lib/alf-io/alf/reader/rash.rb

Overview

Implements an iterator at the interface with the outside world.

This base class provides a default behavior for readers that works with IO objects. It can be safely extended, overriden, or mimiced. This class also provides a registration mechanism to help getting Reader instances for specific file extensions. A typical scenario for using this registration mechanism is as follows:

# Registers a reader kind named :foo, associated with ".foo" file
# extensions and the FooFileDecoder class (typically a subclass of
# Reader)
Reader.register(:foo, [".foo"], FooFileDecoder)

# Later on, you can request a reader instance for a .foo file
r = Reader.reader('/a/path/to/a/file.foo')

# Also, a factory method is automatically installed on the Reader class
# itself. This factory method can be used with a String, or an IO object.
r = Reader.foo([a path or a IO object])

Direct Known Subclasses

CSV, JSON, Rash

Defined Under Namespace

Classes: CSV, JSON, Rash

Constant Summary collapse

DEFAULT_OPTIONS =

Default reader options

{}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Support::Registry

listen, listeners, register, registered

Methods included from Engine::Cog

#to_dot, #to_relation

Constructor Details

#initialize(input, options = {}) ⇒ Reader

Creates a reader instance.



115
116
117
118
119
# File 'lib/alf-io/alf/reader.rb', line 115

def initialize(input, options = {})
  @input   = input
  @path    = Path(@input)
  @options = self.class.const_get(:DEFAULT_OPTIONS).merge(options)
end

Instance Attribute Details

#inputString, ...



103
104
105
# File 'lib/alf-io/alf/reader.rb', line 103

def input
  @input
end

#optionsHash



109
110
111
# File 'lib/alf-io/alf/reader.rb', line 109

def options
  @options
end

#pathObject (readonly)

Returns the value of attribute path.



106
107
108
# File 'lib/alf-io/alf/reader.rb', line 106

def path
  @path
end

Class Method Details

.by_mime_type(mime_type, *args) ⇒ Renderer

Returns a Reader instance for the given mime type.



79
80
81
82
83
84
85
# File 'lib/alf-io/alf/reader.rb', line 79

def by_mime_type(mime_type, *args)
  if r = registered.find{|_,_,c| c.mime_type == mime_type}
    r.last.new(*args)
  else
    raise UnsupportedMimeTypeError, "No reader for `#{mime_type}`"
  end
end

.coerce(arg) ⇒ Object

Coerces ‘arg` to a Reader instance.



64
65
66
67
68
69
70
71
# File 'lib/alf-io/alf/reader.rb', line 64

def coerce(arg)
  case arg
  when Reader       then arg
  when IO, StringIO then rash(arg)
  else
    raise ArgumentError, "Unable to coerce `#{arg}` to a reader"
  end
end

.reader(source, *args) ⇒ Reader

Returns a Reader on ‘source` denoting a physical representation of a relation.

Raises:

  • (ArgumentError)

    if ‘source` is not recognized or no reader can be found.



51
52
53
54
55
56
57
58
59
# File 'lib/alf-io/alf/reader.rb', line 51

def reader(source, *args)
  if Path.like?(source)
    has_reader_for_ext!(Path(source).extname).new(source, *args)
  elsif args.empty?
    coerce(source)
  else
    raise ArgumentError, "Unable to return a reader for `#{source}`"
  end
end

.register(name, extensions, clazz) ⇒ Object

Registers a reader class associated with specific file extensions.

Registered class must provide a constructor with the following signature ‘new(path_or_io, connection = nil, options = {})`. The registration name must be a symbol which can safely be used as a ruby method name. A factory method of that name and signature is automatically installed on the Reader class.



40
41
42
# File 'lib/alf-io/alf/reader.rb', line 40

def register(name, extensions, clazz)
  super([name, extensions, clazz], Reader)
end

Instance Method Details

#eachObject

Yields each tuple in turn

yields the block with line2tuple(line) on each of them. This method may be overriden if this behavior does not fit reader’s needs.



126
127
128
129
130
131
132
# File 'lib/alf-io/alf/reader.rb', line 126

def each
  return to_enum unless block_given?
  each_input_line do |line|
    tuple = line2tuple(line)
    yield tuple unless tuple.nil?
  end
end