object_table 0.1.0 → 0.2.0
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 +249 -56
- data/lib/object_table/basic_grid.rb +1 -1
- data/lib/object_table/group.rb +10 -0
- data/lib/object_table/grouped.rb +8 -13
- data/lib/object_table/masked_column.rb +4 -2
- data/lib/object_table/static_view.rb +24 -0
- data/lib/object_table/table_methods.rb +21 -9
- data/lib/object_table/temp_grouped.rb +1 -1
- data/lib/object_table/version.rb +1 -1
- data/lib/object_table/view.rb +46 -7
- data/lib/object_table.rb +8 -7
- data/spec/object_table/basic_grid_spec.rb +20 -0
- data/spec/object_table/grouped_spec.rb +52 -7
- data/spec/object_table/static_view_spec.rb +10 -0
- data/spec/object_table/temp_grouped_spec.rb +38 -0
- data/spec/object_table/view_spec.rb +61 -106
- data/spec/object_table_spec.rb +29 -0
- data/spec/subclassing_spec.rb +164 -0
- data/spec/support/object_table_example.rb +49 -11
- data/spec/{object_table/temp_view_spec.rb → support/view_example.rb} +50 -86
- metadata +10 -5
- data/lib/object_table/temp_view.rb +0 -63
@@ -0,0 +1,164 @@
|
|
1
|
+
require 'object_table'
|
2
|
+
|
3
|
+
#
|
4
|
+
# spec: kind of proof of concept on how to extend a table
|
5
|
+
# and any children views, groups etc.
|
6
|
+
#
|
7
|
+
# the idea is that we can make a mixin and make it available
|
8
|
+
# to the table and also whenever we filter (#where), group (#group)
|
9
|
+
# or #clone
|
10
|
+
#
|
11
|
+
describe 'Subclassing ObjectTable and friends' do
|
12
|
+
|
13
|
+
class MyTable < ObjectTable
|
14
|
+
module Mixin
|
15
|
+
Table = MyTable
|
16
|
+
|
17
|
+
def a_plus_b
|
18
|
+
a + b
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
include Mixin
|
23
|
+
|
24
|
+
class StaticView < StaticView; include Mixin; end
|
25
|
+
class View < View; include Mixin; end
|
26
|
+
class Group < Group; include Mixin; end
|
27
|
+
end
|
28
|
+
|
29
|
+
let(:table){ MyTable.new(a: 0...100, b: 100.times.map{rand}) }
|
30
|
+
|
31
|
+
subject{ table }
|
32
|
+
|
33
|
+
it 'should have the mixin method available' do
|
34
|
+
expect(subject.a_plus_b).to eq (subject.a + subject.b)
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#clone' do
|
38
|
+
it 'should be an instance of the table subclass' do
|
39
|
+
expect(table.clone).to be_a MyTable
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#apply' do
|
44
|
+
context 'with a block returning a grid' do
|
45
|
+
subject{ table.apply{ ObjectTable::BasicGrid[col1: [4, 5, 6]] } }
|
46
|
+
|
47
|
+
it 'should coerce to the table subclass' do
|
48
|
+
expect(subject).to be_a MyTable
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '#where' do
|
54
|
+
subject{ table.where{a > 50} }
|
55
|
+
|
56
|
+
it 'should create view extending the mixin' do
|
57
|
+
expect(subject).to be_a ObjectTable::View
|
58
|
+
expect(subject).to be_a MyTable::Mixin
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should have the mixin method available' do
|
62
|
+
expect(subject.a_plus_b).to eq (subject.a + subject.b)
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '#clone' do
|
66
|
+
it 'should be an instance of the subclass' do
|
67
|
+
expect(subject.clone).to be_a MyTable
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#apply' do
|
72
|
+
subject{ table.where{a > 50}.apply{self} }
|
73
|
+
|
74
|
+
it 'should create static view extending the mixin' do
|
75
|
+
expect(subject).to be_a ObjectTable::StaticView
|
76
|
+
expect(subject).to be_a MyTable::Mixin
|
77
|
+
end
|
78
|
+
|
79
|
+
describe '#clone' do
|
80
|
+
it 'should be an instance of the table subclass' do
|
81
|
+
expect(subject.clone).to be_a MyTable
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe '#group_by' do
|
89
|
+
subject{ table.group_by{{gt_50: a > 50}} }
|
90
|
+
|
91
|
+
describe '#each' do
|
92
|
+
let(:groups) do
|
93
|
+
_groups = []
|
94
|
+
subject.each{ _groups << self }
|
95
|
+
_groups
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should give groups extending the Mixin' do
|
99
|
+
groups.each do |g|
|
100
|
+
expect(g).to be_a ObjectTable::Group
|
101
|
+
expect(g).to be_a MyTable::Mixin
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should have the mixin method available to the groups' do
|
106
|
+
groups.each do |g|
|
107
|
+
expect(g.a_plus_b).to eql (g.a + g.b)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe '#clone' do
|
112
|
+
it 'should be an instance of the table subclass' do
|
113
|
+
groups.each do |g|
|
114
|
+
expect(g.clone).to be_a MyTable
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe '#apply' do
|
121
|
+
let(:groups) do
|
122
|
+
_groups = []
|
123
|
+
subject.apply{ _groups << self; nil }
|
124
|
+
_groups
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'should give groups extending the mixin' do
|
128
|
+
groups.each do |g|
|
129
|
+
expect(g).to be_a ObjectTable::Group
|
130
|
+
expect(g).to be_a MyTable::Mixin
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'should have the mixin method available to the groups' do
|
135
|
+
groups.each do |g|
|
136
|
+
expect(g.a_plus_b).to eql (g.a + g.b)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'should aggregate into a subclassed table' do
|
141
|
+
expect(subject.apply{nil}).to be_a MyTable
|
142
|
+
end
|
143
|
+
|
144
|
+
describe '#clone' do
|
145
|
+
it 'should be an instance of the table subclass' do
|
146
|
+
groups.each do |g|
|
147
|
+
expect(g.clone).to be_a MyTable
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
describe '#sort_by' do
|
157
|
+
let(:sorted){ table.sort_by(table.b) }
|
158
|
+
|
159
|
+
it 'should return an instance of the table subclass' do
|
160
|
+
expect(sorted).to be_a MyTable
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
@@ -9,13 +9,15 @@ RSpec.shared_examples 'an object table' do |cls|
|
|
9
9
|
if @cls == ObjectTable
|
10
10
|
table
|
11
11
|
|
12
|
-
|
12
|
+
# for views, basically add one row to the parent and mask the view
|
13
|
+
# so that it only includes the original rows
|
14
|
+
elsif @cls == ObjectTable::View
|
13
15
|
table.stack! ObjectTable::BasicGrid[table.columns.map{|k, v| [k, v.max]}]
|
14
16
|
column = table.colnames.first
|
15
17
|
table[column][-1] += 1
|
16
18
|
table.where{table[column] < table[column][-1]}
|
17
19
|
|
18
|
-
elsif @cls == ObjectTable::
|
20
|
+
elsif @cls == ObjectTable::StaticView
|
19
21
|
table.stack! ObjectTable::BasicGrid[table.columns.map{|k, v| [k, v.max]}]
|
20
22
|
column = table.colnames.first
|
21
23
|
table[column][-1] += 1
|
@@ -159,6 +161,14 @@ EOS
|
|
159
161
|
expect(table.nrows).to eql 0
|
160
162
|
end
|
161
163
|
end
|
164
|
+
|
165
|
+
context 'on a table with empty columns' do
|
166
|
+
let(:table){ ObjectTable.new(a: []) }
|
167
|
+
|
168
|
+
it 'should return 0' do
|
169
|
+
expect(table.nrows).to eql 0
|
170
|
+
end
|
171
|
+
end
|
162
172
|
end
|
163
173
|
|
164
174
|
describe 'column methods' do
|
@@ -230,24 +240,52 @@ EOS
|
|
230
240
|
describe '#apply' do
|
231
241
|
let(:table){ ObjectTable.new(col1: [1, 2, 3], col2: 5) }
|
232
242
|
|
233
|
-
it 'should
|
243
|
+
it 'should return the results of the block' do
|
234
244
|
expect(subject.apply{ col1 }).to eql subject.col1
|
235
|
-
expect(subject.apply{ col2.sum }).to eql subject.col2.sum
|
236
245
|
end
|
237
246
|
|
238
247
|
context 'with a block returning a grid' do
|
239
|
-
|
248
|
+
let(:result) { subject.apply{ ObjectTable::BasicGrid[col1: [4, 5, 6]] } }
|
240
249
|
|
241
250
|
it 'should coerce to a table' do
|
242
|
-
expect(
|
251
|
+
expect(result).to be_a ObjectTable
|
243
252
|
end
|
244
253
|
end
|
245
254
|
|
246
255
|
it 'should have access to a BasicGrid shortcut' do
|
247
|
-
result =
|
256
|
+
result = subject.apply{ @R[value: col1 + 5] }
|
248
257
|
expect(result).to be_a ObjectTable
|
249
|
-
expect(result.value).to eql (
|
258
|
+
expect(result.value).to eql (subject.col1 + 5)
|
250
259
|
end
|
260
|
+
|
261
|
+
context 'when the block takes an argument' do
|
262
|
+
it 'should not evaluate in the context of the table' do
|
263
|
+
rspec_context = self
|
264
|
+
|
265
|
+
subject.apply do |tbl|
|
266
|
+
receiver = eval('self', binding)
|
267
|
+
expect(receiver).to_not be subject
|
268
|
+
expect(receiver).to be rspec_context
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
it 'should pass the table into the block' do
|
273
|
+
subject.apply do |tbl|
|
274
|
+
expect(tbl).to eq subject
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
context 'when the block takes no arguments' do
|
280
|
+
it 'should call the block in the context of the table' do
|
281
|
+
_ = self
|
282
|
+
subject.apply do
|
283
|
+
receiver = eval('self', binding)
|
284
|
+
_.expect(receiver).to _.eq _.subject
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
251
289
|
end
|
252
290
|
|
253
291
|
describe '#where' do
|
@@ -256,15 +294,15 @@ EOS
|
|
256
294
|
let(:filtered){ subject.where &block }
|
257
295
|
|
258
296
|
it 'should return a temp view' do
|
259
|
-
expect(filtered).to be_a ObjectTable::
|
297
|
+
expect(filtered).to be_a ObjectTable::View
|
260
298
|
expect(filtered.instance_eval('@filter')).to eql block
|
261
299
|
end
|
262
300
|
end
|
263
301
|
|
264
|
-
describe '#
|
302
|
+
describe '#group_by' do
|
265
303
|
let(:table){ ObjectTable.new(col1: [1, 2, 3], col2: 5) }
|
266
304
|
let(:block){ Proc.new{col1 > 1} }
|
267
|
-
let(:grouped){ subject.
|
305
|
+
let(:grouped){ subject.group_by &block }
|
268
306
|
|
269
307
|
it 'should return groups' do
|
270
308
|
expect(grouped).to be_a ObjectTable::TempGrouped
|
@@ -1,100 +1,62 @@
|
|
1
1
|
require 'object_table'
|
2
|
-
require 'object_table/temp_view'
|
3
2
|
|
4
|
-
|
3
|
+
RSpec.shared_examples 'a table view' do |cls|
|
4
|
+
before do
|
5
|
+
@cls = cls
|
6
|
+
end
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
+
def _make_relevant_view(table, block)
|
9
|
+
if @cls == ObjectTable::View
|
10
|
+
@cls.new(table, &block)
|
8
11
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
+
elsif @cls == ObjectTable::StaticView
|
13
|
+
indices = table.apply(&block).where
|
14
|
+
@cls.new(table, indices)
|
12
15
|
|
13
|
-
|
14
|
-
|
15
|
-
table[:col1] = [5, 6, 7]
|
16
|
-
expect(subject).to eql ObjectTable.new(col1: [5, 6, 7], col2: 5)
|
16
|
+
else
|
17
|
+
nil
|
17
18
|
end
|
18
19
|
end
|
19
20
|
|
20
|
-
|
21
|
-
let(:table){ ObjectTable.new(col1: [1, 2, 3], col2: 5) }
|
22
|
-
let(:view1){ table.where{col1 > 1} }
|
23
|
-
let(:view2){ view1.where{col1 < 3} }
|
24
|
-
|
25
|
-
it 'should add columns correctly' do
|
26
|
-
view2[:col3] = 5
|
27
|
-
expect(view2.col3.to_a).to eql [5]
|
28
|
-
expect(view1.col3.to_a).to eql [5, nil]
|
29
|
-
expect(table.col3.to_a).to eql [nil, 5, nil]
|
30
|
-
end
|
31
|
-
end
|
21
|
+
subject{ _make_relevant_view(table, block) }
|
32
22
|
|
33
|
-
describe '#
|
23
|
+
describe '#columns' do
|
34
24
|
let(:table){ ObjectTable.new(col1: [1, 2, 3], col2: 5) }
|
35
|
-
let(:block){ Proc.new{col1
|
25
|
+
let(:block){ Proc.new{col1 > 2} }
|
36
26
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
subject.apply(&block)
|
27
|
+
it 'should mask the columns of the parent table' do
|
28
|
+
mask = table.col1 > 2
|
29
|
+
table.columns.each do |k, v|
|
30
|
+
expect(subject.columns[k].to_a).to eql v[mask].to_a
|
31
|
+
end
|
43
32
|
end
|
44
33
|
|
45
|
-
it 'should
|
46
|
-
|
47
|
-
|
48
|
-
expect(view).to receive(:apply) do |&b|
|
49
|
-
expect(b).to be block
|
34
|
+
it 'should make masked columns' do
|
35
|
+
subject.columns.each do |k, v|
|
36
|
+
expect(v).to be_a ObjectTable::MaskedColumn
|
50
37
|
end
|
51
|
-
|
52
|
-
subject.apply(&block)
|
53
38
|
end
|
54
|
-
end
|
55
39
|
|
56
|
-
|
57
|
-
|
58
|
-
let(:block){ Proc.new{col1 + 100} }
|
59
|
-
|
60
|
-
subject{ ObjectTable::TempView.new(table){ col1 > 2 } }
|
40
|
+
context 'with a matrixy narray in a column' do
|
41
|
+
let(:table){ ObjectTable.new(col1: [1, 2, 3], col2: NArray[[1,2,3], [4, 5, 6], [7, 8, 9]] ) }
|
61
42
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
subject.group(&block)
|
66
|
-
end
|
67
|
-
|
68
|
-
it 'should call #group on the view' do
|
69
|
-
view = spy('view')
|
70
|
-
expect(ObjectTable::View).to receive(:new){ view }
|
71
|
-
expect(view).to receive(:group) do |&b|
|
72
|
-
expect(b).to be block
|
43
|
+
it 'should mask the matrixy narray too' do
|
44
|
+
indices = (table.col1 > 2).where
|
45
|
+
expect(subject.columns[:col2]).to eq table.col2[nil, indices]
|
73
46
|
end
|
74
47
|
|
75
|
-
subject.group(&block)
|
76
48
|
end
|
77
49
|
end
|
78
50
|
|
79
|
-
describe '#columns' do
|
80
|
-
let(:table){ ObjectTable.new(col1: [1, 2, 3], col2: 5) }
|
81
|
-
|
82
|
-
subject{ ObjectTable::TempView.new(table){ col1 > 2 } }
|
83
|
-
|
84
|
-
it 'should mask the columns of the parent table' do
|
85
|
-
mask = table.col1 > 2
|
86
|
-
table.columns.each do |k, v|
|
87
|
-
expect(subject.columns[k].to_a).to eql v[mask].to_a
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
51
|
|
92
52
|
describe '#set_column' do
|
93
53
|
let(:table) { ObjectTable.new(col1: [0, 1, 2, 3], col2: 5) }
|
94
|
-
let(:
|
54
|
+
let(:block) { Proc.new{col1 > 0} }
|
55
|
+
let(:view) { _make_relevant_view(table, block) }
|
95
56
|
|
96
|
-
let(:column){ :
|
57
|
+
let(:column){ :col1 }
|
97
58
|
let(:value) { [10, 20, 30] }
|
59
|
+
|
98
60
|
let(:args) { [] }
|
99
61
|
|
100
62
|
subject{ view.set_column(column, value, *args) }
|
@@ -107,7 +69,7 @@ describe ObjectTable::TempView do
|
|
107
69
|
|
108
70
|
it 'should not modify anything outside the view' do
|
109
71
|
subject
|
110
|
-
expect(table.columns[column].to_a).to eql [
|
72
|
+
expect(table.columns[column].to_a).to eql [0] + value
|
111
73
|
end
|
112
74
|
|
113
75
|
end
|
@@ -120,17 +82,8 @@ describe ObjectTable::TempView do
|
|
120
82
|
end
|
121
83
|
end
|
122
84
|
|
123
|
-
context 'with a range' do
|
124
|
-
let(:value){ 0...3 }
|
125
|
-
it 'should assign the range values' do
|
126
|
-
subject
|
127
|
-
expect(view.columns[column].to_a).to eql value.to_a
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
85
|
context 'with the wrong length' do
|
132
86
|
let(:value) { [1, 2] }
|
133
|
-
|
134
87
|
it 'should fail' do
|
135
88
|
expect{subject}.to raise_error
|
136
89
|
end
|
@@ -150,7 +103,7 @@ describe ObjectTable::TempView do
|
|
150
103
|
expect(table.columns).to include column
|
151
104
|
end
|
152
105
|
|
153
|
-
it 'should fill values outside the view with a default
|
106
|
+
it 'should fill values outside the view with a default' do
|
154
107
|
subject
|
155
108
|
default = NArray.new(table.columns[column].typecode, 1)[0]
|
156
109
|
expect(table.columns[column].to_a).to eql [default] + value
|
@@ -165,13 +118,13 @@ describe ObjectTable::TempView do
|
|
165
118
|
end
|
166
119
|
end
|
167
120
|
|
168
|
-
|
121
|
+
context 'when failed to add column' do
|
169
122
|
let(:value){ NArray[1, 2, 3] }
|
170
123
|
|
171
124
|
it 'should not have that column' do
|
172
125
|
expect(view).to receive(:add_column).with(column, value.typecode) do
|
173
|
-
view.columns[column] = ObjectTable::Column.make([0] * 10)
|
174
126
|
table.columns[column] = ObjectTable::Column.make([0] * 10)
|
127
|
+
view.columns[column] = ObjectTable::Column.make([0] * 10)
|
175
128
|
end
|
176
129
|
|
177
130
|
# the assignment is going to chuck an error
|
@@ -180,16 +133,27 @@ describe ObjectTable::TempView do
|
|
180
133
|
expect(table.columns).to_not include column
|
181
134
|
end
|
182
135
|
end
|
136
|
+
end
|
183
137
|
|
138
|
+
context 'with an empty view' do
|
139
|
+
let(:block) { Proc.new{col1 < 0} }
|
140
|
+
|
141
|
+
context 'adding an empty column' do
|
142
|
+
let(:value) { [] }
|
143
|
+
it 'should add the column' do
|
144
|
+
subject
|
145
|
+
expect(view.columns[column].to_a).to eq value
|
146
|
+
end
|
147
|
+
end
|
184
148
|
end
|
185
149
|
|
186
150
|
end
|
187
151
|
|
188
152
|
describe '#pop_column' do
|
189
153
|
let(:table){ ObjectTable.new(col1: [1, 2, 3], col2: 5) }
|
190
|
-
|
191
|
-
let(:view) {
|
192
|
-
let(:name)
|
154
|
+
let(:block){ Proc.new{col1 > 2} }
|
155
|
+
let(:view) { _make_relevant_view(table, block) }
|
156
|
+
let(:name) { :col2 }
|
193
157
|
|
194
158
|
subject{ view.pop_column(name) }
|
195
159
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: object_table
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cheney Lin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: narray
|
@@ -81,11 +81,12 @@ files:
|
|
81
81
|
- lib/object_table.rb
|
82
82
|
- lib/object_table/basic_grid.rb
|
83
83
|
- lib/object_table/column.rb
|
84
|
+
- lib/object_table/group.rb
|
84
85
|
- lib/object_table/grouped.rb
|
85
86
|
- lib/object_table/masked_column.rb
|
87
|
+
- lib/object_table/static_view.rb
|
86
88
|
- lib/object_table/table_methods.rb
|
87
89
|
- lib/object_table/temp_grouped.rb
|
88
|
-
- lib/object_table/temp_view.rb
|
89
90
|
- lib/object_table/version.rb
|
90
91
|
- lib/object_table/view.rb
|
91
92
|
- lib/object_table/view_methods.rb
|
@@ -94,11 +95,13 @@ files:
|
|
94
95
|
- spec/object_table/column_spec.rb
|
95
96
|
- spec/object_table/grouped_spec.rb
|
96
97
|
- spec/object_table/masked_column_spec.rb
|
98
|
+
- spec/object_table/static_view_spec.rb
|
97
99
|
- spec/object_table/temp_grouped_spec.rb
|
98
|
-
- spec/object_table/temp_view_spec.rb
|
99
100
|
- spec/object_table/view_spec.rb
|
100
101
|
- spec/object_table_spec.rb
|
102
|
+
- spec/subclassing_spec.rb
|
101
103
|
- spec/support/object_table_example.rb
|
104
|
+
- spec/support/view_example.rb
|
102
105
|
homepage: https://github.com/lincheney/ruby-object-table
|
103
106
|
licenses:
|
104
107
|
- MIT
|
@@ -128,8 +131,10 @@ test_files:
|
|
128
131
|
- spec/object_table/column_spec.rb
|
129
132
|
- spec/object_table/grouped_spec.rb
|
130
133
|
- spec/object_table/masked_column_spec.rb
|
134
|
+
- spec/object_table/static_view_spec.rb
|
131
135
|
- spec/object_table/temp_grouped_spec.rb
|
132
|
-
- spec/object_table/temp_view_spec.rb
|
133
136
|
- spec/object_table/view_spec.rb
|
134
137
|
- spec/object_table_spec.rb
|
138
|
+
- spec/subclassing_spec.rb
|
135
139
|
- spec/support/object_table_example.rb
|
140
|
+
- spec/support/view_example.rb
|
@@ -1,63 +0,0 @@
|
|
1
|
-
require 'forwardable'
|
2
|
-
require_relative 'view_methods'
|
3
|
-
require_relative 'masked_column'
|
4
|
-
require_relative 'view'
|
5
|
-
|
6
|
-
class ObjectTable::TempView
|
7
|
-
include ObjectTable::ViewMethods
|
8
|
-
|
9
|
-
extend Forwardable
|
10
|
-
def_delegators :make_view, :group, :apply
|
11
|
-
|
12
|
-
def initialize(parent, &block)
|
13
|
-
super()
|
14
|
-
@parent = parent
|
15
|
-
@filter = block
|
16
|
-
end
|
17
|
-
|
18
|
-
def_delegators :@parent, :has_column?
|
19
|
-
|
20
|
-
def get_column(name)
|
21
|
-
col = @parent.get_column(name)
|
22
|
-
ObjectTable::MaskedColumn.mask(col, indices) if col
|
23
|
-
end
|
24
|
-
alias_method :[], :get_column
|
25
|
-
|
26
|
-
def make_view
|
27
|
-
ObjectTable::View.new @parent, indices
|
28
|
-
end
|
29
|
-
|
30
|
-
def clone
|
31
|
-
cols = ObjectTable::BasicGrid[@parent.columns.map{|k, v| [k, v[indices]]}]
|
32
|
-
ObjectTable.new(cols)
|
33
|
-
end
|
34
|
-
|
35
|
-
def inspect(*args)
|
36
|
-
cache_columns{ super }
|
37
|
-
rescue NoMethodError => e
|
38
|
-
raise Exception.new(e)
|
39
|
-
end
|
40
|
-
|
41
|
-
def indices
|
42
|
-
@indices or NArray.int(@parent.nrows).indgen![@parent.apply &@filter]
|
43
|
-
end
|
44
|
-
|
45
|
-
def cache_indices(&block)
|
46
|
-
@indices = indices
|
47
|
-
value = block.call()
|
48
|
-
@indices = nil
|
49
|
-
value
|
50
|
-
end
|
51
|
-
|
52
|
-
def columns
|
53
|
-
@columns or super
|
54
|
-
end
|
55
|
-
|
56
|
-
def cache_columns(&block)
|
57
|
-
@columns = columns
|
58
|
-
value = block.call()
|
59
|
-
@columns = nil
|
60
|
-
value
|
61
|
-
end
|
62
|
-
|
63
|
-
end
|