flat 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/flat.gemspec +2 -2
- data/lib/flat.rb +1 -72
- data/lib/flat/field.rb +6 -6
- data/lib/flat/file.rb +147 -0
- data/lib/flat/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba9c2c820dfbb6f95015b50eb4d64ea957fc9ba4
|
4
|
+
data.tar.gz: 283cfca9ab988ae636d3d494ef0fad7dc4fb4a20
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 148837045c6baa0812f6ba33df1736677357efa347c4c17c30f6c979774cbaa4c83fc92e6aabe14ee7a2c363e577a74d7d9570e4c4162dcb3d7a80f2b2bdbfbb
|
7
|
+
data.tar.gz: 09f18cfd8de97a106785fa52ad806e8e0d9578df0201fcd516ada10e6e5dfcaa4e97ed6c2dd70a6797808bbc026c9eaf1662e2b8e21be412ef7fef50ed3c58b3
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
[![Coverage Status](https://coveralls.io/repos/juicyparts/flat/badge.png?branch=master)](https://coveralls.io/r/juicyparts/flat)
|
5
5
|
[![Gem Version](https://badge.fury.io/rb/flat.svg)](http://badge.fury.io/rb/flat)
|
6
6
|
|
7
|
-
Flat is a library to make processing Flat Flies as easy as CSV files. Easily process flat files with Flat. Specify the format in a subclass of Flat::File and read and write until the cows come home.
|
7
|
+
[Flat](https://github.com/juicyparts/flat) is a library to make processing Flat Flies as easy as CSV files. Easily process flat files with Flat. Specify the format in a subclass of Flat::File and read and write until the cows come home.
|
8
8
|
|
9
9
|
## Installation
|
10
10
|
|
@@ -42,7 +42,7 @@ people might look like this:
|
|
42
42
|
pad :autoname, width: 2
|
43
43
|
|
44
44
|
def self.trim(v)
|
45
|
-
v.
|
45
|
+
v.strip
|
46
46
|
end
|
47
47
|
|
48
48
|
end
|
data/flat.gemspec
CHANGED
@@ -18,8 +18,8 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
# Ruby
|
22
|
-
spec.required_ruby_version = '>=
|
21
|
+
# Ruby 1.9.3 and above
|
22
|
+
spec.required_ruby_version = '>= 1.9.3'
|
23
23
|
spec.post_install_message = "Thanks for installing!"
|
24
24
|
spec.metadata = {
|
25
25
|
"source_code" => 'https://github.com/juicyparts/flat',
|
data/lib/flat.rb
CHANGED
@@ -3,77 +3,6 @@ require 'extlib'
|
|
3
3
|
require 'flat/version'
|
4
4
|
require 'flat/file'
|
5
5
|
|
6
|
-
|
7
|
-
#
|
8
|
-
# Flat files are typically plain/text files containing many lines of text, or
|
9
|
-
# data. Each line, or record, consists of one or more fields. However, unlike
|
10
|
-
# CSV (comma spearated value) files, there are no delimiters to define where
|
11
|
-
# values end or begin. Flat provides a mechaism of defining a file's record
|
12
|
-
# structure, allowing users to iterate over a given file and access its data as
|
13
|
-
# typical Ruby objects (String, Numeric, Date, Booleans, etc.).
|
14
|
-
#
|
15
|
-
# == Specification
|
16
|
-
#
|
17
|
-
# A flat file's specification is defined within the subclass of Flat::File. The
|
18
|
-
# use of <tt>add_field</tt> and <tt>pad</tt> define and document the record
|
19
|
-
# structure.
|
20
|
-
#
|
21
|
-
# Given the following
|
22
|
-
# # Actual plain text, flat file data, 29 bytes
|
23
|
-
# #
|
24
|
-
# # 10 20
|
25
|
-
# # 012345678901234567890123456789
|
26
|
-
# # Walt Whitman 18190531
|
27
|
-
# # Linus Torvalds 19691228
|
28
|
-
#
|
29
|
-
# class People < Flat::File
|
30
|
-
# add_field :first_name, width: 10, filter: :trim
|
31
|
-
# add_field :last_name, width: 10, filter: ->(v) { v.strip }
|
32
|
-
# add_field :birthday, width: 8, filter: BirthdayFilter
|
33
|
-
# pad :autoname, width: 2
|
34
|
-
# end
|
35
|
-
#
|
36
|
-
# You will notice the minimum required information is field name and width. The
|
37
|
-
# special case is with <tt>pad</tt>; you can specifiy a name but the general
|
38
|
-
# approach is to let Flat::File name it for you.
|
39
|
-
#
|
40
|
-
# An alternate method of specifying fields is to pass a block to the
|
41
|
-
# <tt>add_field</tt> method. When using the block method you do not have to
|
42
|
-
# specifiy the name first. However, you do need to set the name inside the
|
43
|
-
# block. The value yieled to the block is an instance of Field::Definition.
|
44
|
-
#
|
45
|
-
# class People < FlatFile
|
46
|
-
# add_field do |fd|
|
47
|
-
# fd.name = :first_name
|
48
|
-
# fd.width = 10
|
49
|
-
# fd.add_filter ->(v) { v.strip }
|
50
|
-
# fd.add_formatter ->(v) { v.strip }
|
51
|
-
# end
|
52
|
-
#
|
53
|
-
# add_field :last_name do |fd|
|
54
|
-
# fd.width = 10
|
55
|
-
# fd.add_filter ->(v) { v.strip }
|
56
|
-
# fd.add_formatter ->(v) { v.strip }
|
57
|
-
# end
|
58
|
-
#
|
59
|
-
# end
|
60
|
-
#
|
61
|
-
# == Reading Data
|
62
|
-
#
|
63
|
-
# == Writing Data
|
64
|
-
#
|
65
|
-
# == Filters
|
66
|
-
#
|
67
|
-
# == Formatters
|
68
|
-
#
|
69
|
-
# == Exceptions
|
70
|
-
#
|
71
|
-
# * +FlatFileError+ - Generic error class and superclass of all other errors raised by Flat.
|
72
|
-
# * +LayoutConstructorError+ - The specified layout definition was not valid.
|
73
|
-
# * +RecordLengthError+ - Generic error having to do with line lengths not meeting expectations.
|
74
|
-
# * +ShortRecordError+ - The incoming line was shorter than expections defined.
|
75
|
-
# * +LongRecordError+ - The incoming line was longer than expections defined.
|
76
|
-
#
|
77
|
-
module Flat
|
6
|
+
module Flat #:nodoc
|
78
7
|
include Extlib
|
79
8
|
end
|
data/lib/flat/field.rb
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
# = Field
|
3
3
|
#
|
4
4
|
# A field definition tracks information that's necessary for
|
5
|
-
#
|
6
|
-
# added to a subclass of
|
5
|
+
# Flat::File to process a particular field. This is typically
|
6
|
+
# added to a subclass of Flat::File like so:
|
7
7
|
#
|
8
|
-
# class SomeFile <
|
8
|
+
# class SomeFile < Flat::File
|
9
9
|
# add_field :some_field_name, :width => 35
|
10
10
|
# end
|
11
11
|
#
|
@@ -19,13 +19,13 @@ module Field
|
|
19
19
|
module ClassMethods
|
20
20
|
|
21
21
|
##
|
22
|
-
# Add a field to the
|
22
|
+
# Add a field to the Flat::File subclass. Options can include
|
23
23
|
#
|
24
24
|
# :width - number of characters in field (default 10)
|
25
25
|
# :filter - callack, lambda or code block for processing during reading
|
26
26
|
# :formatter - callback, lambda, or code block for processing during writing
|
27
27
|
#
|
28
|
-
# class SomeFile <
|
28
|
+
# class SomeFile < Flat::File
|
29
29
|
# add_field :some_field_name, :width => 35
|
30
30
|
# end
|
31
31
|
#
|
@@ -91,7 +91,7 @@ module Field
|
|
91
91
|
|
92
92
|
##
|
93
93
|
# Create a new FieldDef, having name and width. parent is a reference to the
|
94
|
-
#
|
94
|
+
# Flat::File subclass that contains this field definition. This reference is
|
95
95
|
# needed when calling filters if they are specified using a symbol.
|
96
96
|
#
|
97
97
|
# Options can be :padding (if present and a true value, field is marked as a
|
data/lib/flat/file.rb
CHANGED
@@ -7,6 +7,153 @@ require 'flat/read_operations'
|
|
7
7
|
|
8
8
|
# = Flat::File
|
9
9
|
#
|
10
|
+
# Flat files are typically plain/text files containing many lines of text, or
|
11
|
+
# data. Each line, or record, consists of one or more fields. However, unlike
|
12
|
+
# CSV (comma separated value) files, there are no delimiters to define where
|
13
|
+
# values end or begin. Flat provides a mechanism of defining a file's record
|
14
|
+
# structure, allowing users to iterate over a given file and access its data as
|
15
|
+
# typical Ruby objects (String, Numeric, Date, Booleans, etc.).
|
16
|
+
#
|
17
|
+
# == Specification
|
18
|
+
#
|
19
|
+
# A flat file's specification is defined within the subclass of Flat::File. The
|
20
|
+
# use of <tt>add_field</tt> and <tt>pad</tt> define and document the record
|
21
|
+
# structure.
|
22
|
+
#
|
23
|
+
# # Actual plain text, flat file data, 29 bytes
|
24
|
+
# #
|
25
|
+
# # 10 20
|
26
|
+
# # 012345678901234567890123456789
|
27
|
+
# # Walt Whitman 18190531
|
28
|
+
# # Linus Torvalds 19691228
|
29
|
+
#
|
30
|
+
# class People < Flat::File
|
31
|
+
# add_field :first_name, width: 10, filter: :trim
|
32
|
+
# add_field :last_name, width: 10, filter: ->(v) { v.strip }
|
33
|
+
# add_field :birthday, width: 8, filter: BirthdayFilter
|
34
|
+
# pad :autoname, width: 2
|
35
|
+
#
|
36
|
+
# def self.trim(v)
|
37
|
+
# v.strip
|
38
|
+
# end
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# You will notice the minimum required information is field name and width. The
|
42
|
+
# special case is with <tt>pad</tt>; you can specify a name but the general
|
43
|
+
# approach is to let Flat::File name it for you.
|
44
|
+
#
|
45
|
+
# An alternate method of specifying fields is to pass a block to the
|
46
|
+
# <tt>add_field</tt> method. When using the block method you do not have to
|
47
|
+
# specify the name first. However, you do need to set the name inside the
|
48
|
+
# block. The value yielded to the block is an instance of Field::Definition.
|
49
|
+
#
|
50
|
+
# class People < Flat::File
|
51
|
+
# add_field do |fd|
|
52
|
+
# fd.name = :first_name
|
53
|
+
# fd.width = 10
|
54
|
+
# fd.add_filter ->(v) { v.strip }
|
55
|
+
# fd.add_formatter ->(v) { v.strip }
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# add_field :last_name do |fd|
|
59
|
+
# fd.width = 10
|
60
|
+
# fd.add_filter ->(v) { v.strip }
|
61
|
+
# fd.add_formatter ->(v) { v.strip }
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# == Reading Data
|
67
|
+
#
|
68
|
+
# After your Flat::File has been defined you will be able to read data from
|
69
|
+
# an actual file. Flat::File does not manage the opening and closing of Files
|
70
|
+
# or other IO instances (e.g. StringIO).
|
71
|
+
#
|
72
|
+
# data_file = File.open('somefile.dat', 'r')
|
73
|
+
#
|
74
|
+
# People.new.each_record(data_file) do |person|
|
75
|
+
# puts "First Name: #{person.first_name}" # => Walter
|
76
|
+
# puts "Last Name : #{person.last_name}" # => White
|
77
|
+
# puts "Birthday : #{person.birthday}" # => 19590907
|
78
|
+
# end
|
79
|
+
#
|
80
|
+
# data_file.close
|
81
|
+
#
|
82
|
+
# +each_record+ yields a Record::Definition and the line of text that
|
83
|
+
# produced it. This object will respond to the field names defined by
|
84
|
+
# +add_field+. Plus, depending on the filters defined, the resulting data
|
85
|
+
# can be nearly any Ruby type: String, Symbol, Boolean, Date, etc. This allows
|
86
|
+
# you to deal with the data as it was intended.
|
87
|
+
#
|
88
|
+
# == Writing Data
|
89
|
+
#
|
90
|
+
# <em>Slated for a future release.</em>
|
91
|
+
#
|
92
|
+
# == Filters
|
93
|
+
#
|
94
|
+
# When adding new fields you can specify a filter through which the incoming
|
95
|
+
# data will be passed. In the absence of a filter the resulting values from the
|
96
|
+
# Record::Definition will be the raw text as found in the flat file.
|
97
|
+
#
|
98
|
+
# You can define filters in 1 of four ways: Symbol, Proc, Class, or Object.
|
99
|
+
#
|
100
|
+
# Operationally they all function the same way: used when reading the raw text
|
101
|
+
# in the file to produce a filtered value for storage in a Record::Definition.
|
102
|
+
#
|
103
|
+
# === Defined as a Symbol
|
104
|
+
#
|
105
|
+
# add_field :first_name, width: 10, filter: :trim
|
106
|
+
#
|
107
|
+
# +trim+, in this case, must be defined on the Flat::File subclass.
|
108
|
+
#
|
109
|
+
# def self.trim(v)
|
110
|
+
# v.strip
|
111
|
+
# end
|
112
|
+
#
|
113
|
+
# Use this method when more control over the filtering is required, such as
|
114
|
+
# handling Date parsing errors.
|
115
|
+
#
|
116
|
+
# === Defined as a Proc
|
117
|
+
#
|
118
|
+
# add_field :last_name, width: 10, filter: ->(v) { v.strip }
|
119
|
+
#
|
120
|
+
# The proc is stored and later called when needed. If the filtering
|
121
|
+
# requirements are easy and direct, this method is appropriate.
|
122
|
+
#
|
123
|
+
# === Defined as a Class or Object
|
124
|
+
#
|
125
|
+
# add_field :birthday, width: 8, filter: BirthdayFilter
|
126
|
+
# add_field :birthday, width: 8, filter: BirthdayFilter.new
|
127
|
+
#
|
128
|
+
# The Class or Object used must respond to +filter+. This method is very
|
129
|
+
# similar to the +Symbol+ method, expect there is only 1 method to define.
|
130
|
+
#
|
131
|
+
# def self.filter(v)
|
132
|
+
# date = Date.parse(v) rescue $!
|
133
|
+
# return date unless date.is_a? ArgumentError
|
134
|
+
# nil
|
135
|
+
# end
|
136
|
+
#
|
137
|
+
# def filter(v)
|
138
|
+
# self.class.filter(v)
|
139
|
+
# end
|
140
|
+
#
|
141
|
+
# == Formatters
|
142
|
+
#
|
143
|
+
# <em>Slated for a future release.</em>
|
144
|
+
#
|
145
|
+
# == Layouts
|
146
|
+
#
|
147
|
+
# <em>Slated for a future release.</em>
|
148
|
+
#
|
149
|
+
# == Exceptions
|
150
|
+
#
|
151
|
+
# * +FlatFileError+ - Generic error class and superclass of all other errors raised by Flat.
|
152
|
+
# * +LayoutConstructorError+ - The specified layout definition was not valid.
|
153
|
+
# * +RecordLengthError+ - Generic error having to do with line lengths not meeting expectations.
|
154
|
+
# * +ShortRecordError+ - The incoming line was shorter than expectations defined.
|
155
|
+
# * +LongRecordError+ - The incoming line was longer than expectations defined.
|
156
|
+
#
|
10
157
|
class Flat::File
|
11
158
|
include Errors
|
12
159
|
include FileData
|
data/lib/flat/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mel Riffe
|
@@ -214,7 +214,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
214
214
|
requirements:
|
215
215
|
- - ">="
|
216
216
|
- !ruby/object:Gem::Version
|
217
|
-
version:
|
217
|
+
version: 1.9.3
|
218
218
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
219
219
|
requirements:
|
220
220
|
- - ">="
|