Class: TextTable
- Inherits:
-
Object
show all
- Defined in:
- lib/texttable.rb
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
-
#[](field, val = nil) ⇒ Object
-
#[]=(field, value) ⇒ Object
-
#add(obj, *args) ⇒ Object
(also: #<<)
-
#as_json(obj = defined?(ConfigHash) ? +{} : {}) ⇒ Object
-
#convert_key(key) ⇒ Object
-
#csv(sep = ',', encoding: nil, **kw) ⇒ Object
-
#each ⇒ Object
-
#each_pair ⇒ Object
-
#fields ⇒ Object
-
#index(field, auto = false) ⇒ Object
-
#index!(field) ⇒ Object
-
#initialize(*args) ⇒ TextTable
constructor
A new instance of TextTable.
-
#lookup!(field) ⇒ Object
-
#method_missing(field, *args) ⇒ Object
-
#next!(step = 1) ⇒ Object
-
#prev!(step = 1) ⇒ Object
-
#psv(**kw) ⇒ Object
-
#row(row = nil) ⇒ Object
-
#row=(row) ⇒ Object
-
#show ⇒ Object
-
#show!(list = nil) ⇒ Object
-
#size ⇒ Object
-
#sql(table = 'table', quote: false, timestamps: false, verb: 'insert', out: nil) ⇒ Object
-
#tsv(**kw) ⇒ Object
-
#update(obj, *args) ⇒ Object
-
#vals ⇒ Object
Constructor Details
#initialize(*args) ⇒ TextTable
Returns a new instance of TextTable.
42
43
44
45
46
47
48
49
50
51
52
|
# File 'lib/texttable.rb', line 42
def initialize(*args)
cols = args
cols = cols[0] if cols[0].is_a?(Array) && cols[0][0].is_a?(Array)
cols, *rows = cols if cols[0].is_a?(Array)
rows = *rows[0] if rows && rows[0].is_a?(Array) && rows[0][0].is_a?(Array)
rows = [] if !rows || !rows[0].is_a?(Array) || rows[0].empty?
@cols = Hash.new {|h,k| h[k] = h.size}
@rows = rows
row(0)
cols.each_with_index {|col, i| index!(col || i) }
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(field, *args) ⇒ Object
137
138
139
140
141
142
143
144
145
146
147
148
|
# File 'lib/texttable.rb', line 137
def method_missing(field, *args)
field = field.to_s
equal = field.chomp!('=')
index = index(field, equal)
if equal
value = vals[index] = args.first
elsif index
raise "variable lookup ignores arguments" unless args.empty?
value = vals[index]
end
value
end
|
Instance Attribute Details
#rows ⇒ Object
Returns the value of attribute rows.
2
3
4
|
# File 'lib/texttable.rb', line 2
def rows
@rows
end
|
#values ⇒ Object
Returns the value of attribute values.
2
3
4
|
# File 'lib/texttable.rb', line 2
def values
@values
end
|
Class Method Details
.add(*args) ⇒ Object
16
17
18
|
# File 'lib/texttable.rb', line 16
def add(*args)
new.add(*args)
end
|
.csv(src, sep = ',', encoding: nil, **kw) ⇒ Object
5
6
7
8
9
10
11
12
|
# File 'lib/texttable.rb', line 5
def csv(src, sep=',', encoding: nil, **kw)
require 'csv'
new CSV.read(src || ARGF, {
col_sep: sep,
encoding: encoding ? encoding + ":UTF-8" : nil,
**kw
}.compact)
end
|
.load(data, delim = "\t", headers = true) ⇒ Object
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
# File 'lib/texttable.rb', line 20
def load(data, delim="\t", =true)
case data
when String
if data.include?(delim) text = data
elsif File.exist?(data) text = File.read(data)
end
when File, ARGF
text = data.read
end
text or raise "unable to load #{data.inspect}"
rows = text.split(/\r?\n/).map {|line| line.split(delim).map {|part| part.strip}}
info = new
rows.shift.each_with_index {|col, i| info.index!(col || i) } if
info.rows = rows
info.row(0)
info
end
|
.psv(*args, **kw) ⇒ Object
14
|
# File 'lib/texttable.rb', line 14
def psv(*args, **kw); csv(args.shift, "|" , *args, **kw); end
|
.tsv(*args, **kw) ⇒ Object
13
|
# File 'lib/texttable.rb', line 13
def tsv(*args, **kw); csv(args.shift, "\t", *args, **kw); end
|
Instance Method Details
#[](field, val = nil) ⇒ Object
126
127
128
129
130
|
# File 'lib/texttable.rb', line 126
def [](field, val=nil)
index = index(field)
value = vals[index] if index
value.nil? ? val : value
end
|
#[]=(field, value) ⇒ Object
132
133
134
135
|
# File 'lib/texttable.rb', line 132
def []=(field, value)
index = index!(field)
vals[index] = value
end
|
#add(obj, *args) ⇒ Object
Also known as:
<<
160
161
162
163
|
# File 'lib/texttable.rb', line 160
def add(obj, *args)
@values = @rows[@row = @rows.size] = []
update(obj, *args)
end
|
#as_json(obj = defined?(ConfigHash) ? +{} : {}) ⇒ Object
195
196
197
|
# File 'lib/texttable.rb', line 195
def as_json(obj = defined?(ConfigHash) ? +{} : {})
(@rows || []).map {|r| r.each_with_index.inject(obj) {|h, (v, c)| h[fields[c]] = v; h }}
end
|
#convert_key(key) ⇒ Object
78
79
80
81
82
83
84
|
# File 'lib/texttable.rb', line 78
def convert_key(key)
key.
gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
gsub(/([a-z\d])([A-Z])/, '\1_\2').
gsub(/\W/, '_').
downcase
end
|
#csv(sep = ',', encoding: nil, **kw) ⇒ Object
199
200
201
202
203
204
205
206
207
208
209
210
211
|
# File 'lib/texttable.rb', line 199
def csv(sep=',', encoding: nil, **kw)
require 'csv'
out = kw.key?(:out) ? (kw.delete(:out) || "").dup : nil
csv = CSV.new(out || $stdout, {
col_sep: sep,
encoding: encoding ? encoding + ":UTF-8" : nil,
quote_empty: false, **kw
})
csv << @cols.keys
@rows.each {|vals| csv << vals}
out
end
|
#each ⇒ Object
117
118
119
120
|
# File 'lib/texttable.rb', line 117
def each
@rows or raise "no rows defined"
@rows.each_with_index {|_, row| yield(row(row)) }
end
|
#each_pair ⇒ Object
122
123
124
|
# File 'lib/texttable.rb', line 122
def each_pair
@cols.each {|col, pos| yield col, @values[pos] }
end
|
#fields ⇒ Object
90
91
92
|
# File 'lib/texttable.rb', line 90
def fields
@cols.keys
end
|
#index(field, auto = false) ⇒ Object
54
55
56
57
58
59
60
61
62
63
64
|
# File 'lib/texttable.rb', line 54
def index(field, auto=false)
case field
when String, Symbol
field = convert_key(field)
index = @cols.key?(field) ? @cols[field] : auto ? @cols[field] : nil
when Numeric
field
else
raise "invalid field index #{field.inspect}"
end
end
|
#index!(field) ⇒ Object
66
67
68
|
# File 'lib/texttable.rb', line 66
def index!(field)
index(field, true)
end
|
#lookup!(field) ⇒ Object
70
71
72
73
74
75
76
|
# File 'lib/texttable.rb', line 70
def lookup!(field)
@rows or raise "no rows defined"
index = index(field)
lookup = {}
@rows.each_with_index {|cols, i| lookup[cols[index]] = i}
lookup
end
|
#next!(step = 1) ⇒ Object
105
106
107
|
# File 'lib/texttable.rb', line 105
def next!(step=1)
row(@row += step) if @row < (size - step)
end
|
#prev!(step = 1) ⇒ Object
109
110
111
|
# File 'lib/texttable.rb', line 109
def prev!(step=1)
row(@row -= step) if @row > 0
end
|
#psv(**kw) ⇒ Object
213
|
# File 'lib/texttable.rb', line 213
def psv(**kw); csv("|" , **kw); end
|
#row(row = nil) ⇒ Object
94
95
96
97
98
|
# File 'lib/texttable.rb', line 94
def row(row=nil)
row or return @row
@values = @rows[@row = row]
self
end
|
#row=(row) ⇒ Object
100
101
102
103
|
# File 'lib/texttable.rb', line 100
def row=(row)
@values = @rows[@row = row]
@row
end
|
#show ⇒ Object
167
168
169
|
# File 'lib/texttable.rb', line 167
def show(*)
self
end
|
#show!(list = nil) ⇒ Object
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
|
# File 'lib/texttable.rb', line 171
def show!(list=nil)
meth = list.is_a?(Array) ? list.method(:push) : method(:puts)
join = " │ "
size = @cols.size
full = [@cols.keys] + rows
full.each_with_index do |vals, i| miss = size - vals.size
full[i] += [nil] * miss if miss > 0
full[i] = vals[0...size] if miss < 0
end
lens = full.map {|r| r.map {|c| c.to_s.size}}.transpose.map(&:max)
pict = lens.map {|len| "%-#{len}.#{len}s" }.join(join)
pict = [join, pict, join].join.strip
line = (pict % ([""] * size)).tr("│ ", "•─")
seen = -1
meth["", line]
full.each do |vals|
meth[pict % vals]
meth[line] if (seen += 1) == 0
end
meth[line, "#{seen} rows displayed", ""]
self
end
|
#size ⇒ Object
86
87
88
|
# File 'lib/texttable.rb', line 86
def size
@rows.size
end
|
#sql(table = 'table', quote: false, timestamps: false, verb: 'insert', out: nil) ⇒ Object
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
|
# File 'lib/texttable.rb', line 215
def sql(table='table', quote: false, timestamps: false, verb: 'insert', out: nil)
q = quote ? '`' : ''
flip = @cols.invert
@rows.each do |vals|
list = vals.each_with_index.inject([]) do |list, (item, i)|
item = item.to_s list << "#{q}#{flip[i]}#{q}='#{item.gsub("'","''")}'" if item =~ /\S/
list
end
list.push('created_at=now(), updated_at=now()') if timestamps
if !list.empty?
line = "#{verb} into #{q}#{table}#{q} set #{list * ', '};"
out ? (out << line) : puts(line)
end
end
out
end
|
#tsv(**kw) ⇒ Object
212
|
# File 'lib/texttable.rb', line 212
def tsv(**kw); csv("\t", **kw); end
|
#update(obj, *args) ⇒ Object
150
151
152
153
154
155
156
157
158
|
# File 'lib/texttable.rb', line 150
def update(obj, *args)
obj = [obj, *args] if args.size > 0
case obj
when Hash then obj.each {|k, v| @values[index(k.to_s, true)] = v }
when Array then @values.replace(obj)
else raise "unable to add #{obj.class} objects"
end
self
end
|
#vals ⇒ Object
113
114
115
|
# File 'lib/texttable.rb', line 113
def vals
@values ||= @rows[@row] ||= []
end
|