flat 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
[](https://coveralls.io/r/juicyparts/flat)
|
5
5
|
[](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
|
- - ">="
|