arrayfields 4.5.0 → 4.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -272,6 +272,14 @@ AUTHOR
272
272
  ara.t.howard@gmail.com
273
273
 
274
274
  HISTORY
275
+ 4.6.0
276
+ - Array#fields getter acts as setter if arg given, eg
277
+
278
+ a = []
279
+
280
+ a.fields %w( a b c )
281
+ a['c'] = 42
282
+
275
283
  4.4.0:
276
284
  - working dup method worked in, also deepcopy and clone
277
285
 
data/README.tmpl CHANGED
@@ -92,6 +92,14 @@ AUTHOR
92
92
  ara.t.howard@gmail.com
93
93
 
94
94
  HISTORY
95
+ 4.6.0
96
+ - Array#fields getter acts as setter if arg given, eg
97
+
98
+ a = []
99
+
100
+ a.fields %w( a b c )
101
+ a['c'] = 42
102
+
95
103
  4.4.0:
96
104
  - working dup method worked in, also deepcopy and clone
97
105
 
data/lib/arrayfields.rb CHANGED
@@ -5,7 +5,7 @@
5
5
  # Array#fields= is called
6
6
  #
7
7
  module ArrayFields
8
- self::VERSION = '4.5.0' unless defined? self::VERSION
8
+ self::VERSION = '4.6.0' unless defined? self::VERSION
9
9
  def self.version() VERSION end
10
10
  #
11
11
  # multiton cache of fields - wraps fields and fieldpos map to save memory
@@ -308,7 +308,8 @@
308
308
  #
309
309
  # access to field list
310
310
  #
311
- def fields
311
+ def fields *values
312
+ return(send('fields=', *values)) unless values.empty?
312
313
  @fieldset and @fieldset.fields
313
314
  end
314
315
  end
data/test/memtest.rb CHANGED
@@ -13,6 +13,7 @@ n = Integer((ARGV.shift or (2 ** 16)))
13
13
  end
14
14
 
15
15
  puts "pid <#{ Process.pid }>"
16
+ system "ps wwwaux | grep #{ Process.pid }"
16
17
  print "run top to examine mem usage of <#{ n }> hashes (enter when done) >"
17
18
  STDIN.gets
18
19
  end
@@ -33,6 +34,7 @@ n = Integer((ARGV.shift or (2 ** 16)))
33
34
  end
34
35
 
35
36
  puts "pid <#{ Process.pid }>"
37
+ system "ps wwwaux | grep #{ Process.pid }"
36
38
  print "run top to examine mem usage of <#{ n }> extended arrays (enter when done) >"
37
39
  STDIN.gets
38
40
  end
metadata CHANGED
@@ -1,41 +1,31 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.2
3
- specification_version: 1
4
2
  name: arrayfields
5
3
  version: !ruby/object:Gem::Version
6
- version: 4.5.0
7
- date: 2007-09-18 00:00:00 -06:00
8
- summary: arrayfields
9
- require_paths:
10
- - lib
11
- email: ara.t.howard@noaa.gov
12
- homepage: http://codeforpeople.com/lib/ruby/arrayfields/
13
- rubyforge_project:
14
- description:
15
- autorequire: arrayfields
16
- default_executable:
17
- bindir: bin
18
- has_rdoc: false
19
- required_ruby_version: !ruby/object:Gem::Version::Requirement
20
- requirements:
21
- - - ">"
22
- - !ruby/object:Gem::Version
23
- version: 0.0.0
24
- version:
4
+ version: 4.6.0
25
5
  platform: ruby
26
- signing_key:
27
- cert_chain:
28
- post_install_message:
29
6
  authors:
30
7
  - Ara T. Howard
8
+ autorequire: arrayfields
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-07-13 00:00:00 -06:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: ara.t.howard@noaa.gov
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
31
24
  files:
32
- - a.rb
33
- - arrayfields-4.5.0.gem
34
25
  - gemspec.rb
35
26
  - gen_readme.rb
36
27
  - install.rb
37
28
  - lib
38
- - lib/arrayfields-4.5.0.rb
39
29
  - lib/arrayfields.rb
40
30
  - README
41
31
  - README.tmpl
@@ -48,17 +38,31 @@ files:
48
38
  - test
49
39
  - test/arrayfields.rb
50
40
  - test/memtest.rb
51
- test_files:
52
- - test/arrayfields.rb
41
+ has_rdoc: false
42
+ homepage: http://codeforpeople.com/lib/ruby/arrayfields/
43
+ post_install_message:
53
44
  rdoc_options: []
54
45
 
55
- extra_rdoc_files: []
56
-
57
- executables: []
58
-
59
- extensions: []
60
-
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ version:
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
61
60
  requirements: []
62
61
 
63
- dependencies: []
64
-
62
+ rubyforge_project:
63
+ rubygems_version: 1.0.1
64
+ signing_key:
65
+ specification_version: 2
66
+ summary: arrayfields
67
+ test_files:
68
+ - test/arrayfields.rb
data/a.rb DELETED
@@ -1,8 +0,0 @@
1
- require 'rubygems'
2
- require 'arrayfields'
3
- puts "ruby version : #{RUBY_VERSION}"
4
- puts "gems version : #{Gem::RubyGemsVersion}"
5
- puts "arrayfields version : #{ArrayFields::VERSION}"
6
- require 'rake'
7
- puts 42
8
-
File without changes
@@ -1,434 +0,0 @@
1
- #
2
- # The ArrayFields module implements methods which allow an Array to be indexed
3
- # by String or Symbol. It is not required to manually use this module to
4
- # extend Arrays - they are auto-extended on a per-object basis when
5
- # Array#fields= is called
6
- #
7
- module ArrayFields
8
- self::VERSION = '4.5.0' unless defined? self::VERSION
9
- def self.version() VERSION end
10
- #
11
- # multiton cache of fields - wraps fields and fieldpos map to save memory
12
- #
13
- class FieldSet
14
- class << self
15
- def new fields
16
- @sets[fields] ||= super
17
- end
18
- def init_sets
19
- @sets = {}
20
- end
21
- end
22
-
23
- init_sets
24
-
25
- attr :fields
26
- attr :fieldpos
27
- def initialize fields
28
- raise ArgumentError, "<#{ fields.inspect }> not inject-able" unless
29
- fields.respond_to? :inject
30
-
31
- @fieldpos =
32
- fields.inject({}) do |h, f|
33
- unless String === f or Symbol === f
34
- raise ArgumentError, "<#{ f.inspect }> neither String nor Symbol"
35
- end
36
- h[f] = h.size
37
- h
38
- end
39
-
40
- @fields = fields
41
- end
42
- def pos f
43
- return @fieldpos[f] if @fieldpos.has_key? f
44
- f = f.to_s
45
- return @fieldpos[f] if @fieldpos.has_key? f
46
- f = f.intern
47
- return @fieldpos[f] if @fieldpos.has_key? f
48
- nil
49
- end
50
- end
51
- #
52
- # methods redefined to work with fields as well as numeric indexes
53
- #
54
- def [] idx, *args
55
- if @fieldset and (String === idx or Symbol === idx)
56
- pos = @fieldset.pos idx
57
- return nil unless pos
58
- super(pos, *args)
59
- else
60
- super
61
- end
62
- end
63
- def slice idx, *args
64
- if @fieldset and (String === idx or Symbol === idx)
65
- pos = @fieldset.pos idx
66
- return nil unless pos
67
- super(pos, *args)
68
- else
69
- super
70
- end
71
- end
72
-
73
- def []=(idx, *args)
74
- if @fieldset and (String === idx or Symbol === idx)
75
- pos = @fieldset.pos idx
76
- unless pos
77
- @fieldset.fields << idx
78
- @fieldset.fieldpos[idx] = pos = size
79
- end
80
- super(pos, *args)
81
- else
82
- super
83
- end
84
- end
85
- def at idx
86
- if @fieldset and (String === idx or Symbol === idx)
87
- pos = @fieldset.pos idx
88
- return nil unless pos
89
- super pos
90
- else
91
- super
92
- end
93
- end
94
- def delete_at idx
95
- if @fieldset and (String === idx or Symbol === idx)
96
- pos = @fieldset.pos idx
97
- return nil unless pos
98
- super pos
99
- else
100
- super
101
- end
102
- end
103
- def fill(obj, *args)
104
- idx = args.first
105
- if idx and @fieldset and (String === idx or Symbol === idx)
106
- idx = args.shift
107
- pos = @fieldset.pos idx
108
- super(obj, pos, *args)
109
- else
110
- super
111
- end
112
- end
113
-
114
- def values_at(*idxs)
115
- idxs.flatten!
116
- if @fieldset
117
- idxs.map!{|i| (String === i or Symbol === i) ? @fieldset.pos(i) : i}
118
- end
119
- super(*idxs)
120
- end
121
- def indices(*idxs)
122
- idxs.flatten!
123
- if @fieldset
124
- idxs.map!{|i| (String === i or Symbol === i) ? @fieldset.pos(i) : i}
125
- end
126
- super(*idxs)
127
- end
128
- def indexes(*idxs)
129
- idxs.flatten!
130
- if @fieldset
131
- idxs.map!{|i| (String === i or Symbol === i) ? @fieldset.pos(i) : i}
132
- end
133
- super(*idxs)
134
- end
135
-
136
- def slice!(*args)
137
- ret = self[*args]
138
- self[*args] = nil
139
- ret
140
- end
141
- def each_with_field
142
- each_with_index do |elem, i|
143
- yield elem, @fieldset.fields[i]
144
- end
145
- end
146
- #
147
- # methods which give a hash-like interface
148
- #
149
- def each_pair
150
- each_with_index do |elem, i|
151
- yield @fieldset.fields[i], elem
152
- end
153
- end
154
- def each_key
155
- @fieldset.each{|field| yield field}
156
- end
157
- def each_value *args, &block
158
- each *args, &block
159
- end
160
- def fetch key
161
- self[key] or raise IndexError, 'key not found'
162
- end
163
-
164
- def has_key? key
165
- @fieldset.fields.include? key
166
- end
167
- def member? key
168
- @fieldset.fields.include? key
169
- end
170
- def key? key
171
- @fieldset.fields.include? key
172
- end
173
-
174
- def has_value? value
175
- if respond_to? 'include?'
176
- self.include? value
177
- else
178
- a = []
179
- each{|val| a << val}
180
- a.include? value
181
- end
182
- end
183
- def value? value
184
- if respond_to? 'include?'
185
- self.include? value
186
- else
187
- a = []
188
- each{|val| a << val}
189
- a.include? value
190
- end
191
- end
192
-
193
- def keys
194
- fields
195
- end
196
- def store key, value
197
- self[key] = value
198
- end
199
- def values
200
- if respond_to? 'to_ary'
201
- self.to_ary
202
- else
203
- a = []
204
- each{|val| a << val}
205
- a
206
- end
207
- end
208
-
209
- def to_hash
210
- if respond_to? 'to_ary'
211
- h = {}
212
- @fieldset.fields.zip(to_ary){|f,e| h[f] = e}
213
- h
214
- else
215
- a = []
216
- each{|val| a << val}
217
- h = {}
218
- @fieldset.fields.zip(a){|f,e| h[f] = e}
219
- h
220
- end
221
- end
222
- def to_h
223
- if respond_to? 'to_ary'
224
- h = {}
225
- @fieldset.fields.zip(to_ary){|f,e| h[f] = e}
226
- h
227
- else
228
- a = []
229
- each{|val| a << val}
230
- h = {}
231
- @fieldset.fields.zip(a){|f,e| h[f] = e}
232
- h
233
- end
234
- end
235
-
236
- def update other
237
- other.each{|k,v| self[k] = v}
238
- to_hash
239
- end
240
- def replace other
241
- Hash === other ? update(other) : super
242
- end
243
- def invert
244
- to_hash.invert
245
- end
246
-
247
- def to_pairs
248
- fields.zip values
249
- end
250
- alias_method 'pairs', 'to_pairs'
251
-
252
- def copy
253
- cp = clone
254
- cp.fields = fields.clone
255
- cp
256
- end
257
-
258
- alias_method 'dup', 'copy'
259
- alias_method 'clone', 'copy'
260
-
261
- def deepcopy
262
- cp = Marshal.load(Marshal.dump(self))
263
- cp.fields = Marshal.load(Marshal.dump(self.fields))
264
- cp
265
- end
266
- end
267
- Arrayfields = ArrayFields
268
-
269
- module Arrayfields
270
- def self.new *pairs
271
- pairs = pairs.map{|pair| Enumerable === pair ? pair.to_a : pair}.flatten
272
- raise ArgumentError, "pairs must be evenly sized" unless(pairs.size % 2 == 0)
273
- (( array = [] )).fields = []
274
- 0.step(pairs.size - 2, 2) do |a|
275
- b = a + 1
276
- array[ pairs[a] ] = pairs[b]
277
- end
278
- array
279
- end
280
- def self.[] *pairs
281
- new *pairs
282
- end
283
- end
284
- def Arrayfields(*a, &b) Arrayfields.new(*a, &b) end
285
- #
286
- # Fieldable encapsulates methods in common for classes which may have their
287
- # fields set and subsequently be auto-extended by ArrayFields
288
- #
289
- module Fieldable
290
- #
291
- # sets fields an dynamically extends this Array instance with methods for
292
- # keyword access
293
- #
294
- def fields= fields
295
- extend ArrayFields unless ArrayFields === self
296
-
297
- @fieldset =
298
- if ArrayFields::FieldSet === fields
299
- fields
300
- else
301
- ArrayFields::FieldSet.new fields
302
- end
303
- end
304
- #
305
- # access to fieldset
306
- #
307
- attr_reader :fieldset
308
- #
309
- # access to field list
310
- #
311
- def fields
312
- @fieldset and @fieldset.fields
313
- end
314
- end
315
- #
316
- # Array instances are extened with two methods only: Fieldable#fields= and
317
- # Fieldable#fields. only when Fieldable#fields= is called will the full set
318
- # of ArrayFields methods auto-extend the Array instance. the Array class also
319
- # has added a class generator when the fields are known apriori.
320
- #
321
- class Array
322
- include Fieldable
323
-
324
- class << self
325
- def struct *fields
326
- fields = fields.flatten
327
- Class.new(self) do
328
- include ArrayFields
329
- const_set :FIELDS, ArrayFields::FieldSet.new(fields)
330
- fields.each do |field|
331
- field = field.to_s
332
- if field =~ %r/^[a-zA-Z_][a-zA-Z0-9_]*$/
333
- begin
334
- module_eval <<-code
335
- def #{ field } *a
336
- a.size == 0 ? self['#{ field }'] : (self.#{ field } = a.shift)
337
- end
338
- def #{ field }= value
339
- self['#{ field }'] = value
340
- end
341
- code
342
- rescue SyntaxError
343
- :by_ignoring_it
344
- end
345
- end
346
- end
347
- def initialize *a, &b
348
- super
349
- ensure
350
- @fieldset = self.class.const_get :FIELDS
351
- end
352
- def self.[] *elements
353
- array = new
354
- array.replace elements
355
- array
356
- end
357
- end
358
- end
359
- def fields *fields, &block
360
- (( array = new(&block) )).fields = fields.map{|x| Enumerable === x ? x.to_a : x}.flatten
361
- array
362
- end
363
- end
364
- end
365
- #
366
- # proxy class that allows an array to be wrapped in a way that still allows #
367
- # keyword access. also facilitate usage of ArrayFields with arraylike objects.
368
- # thnx to Sean O'Dell for the suggestion.
369
- #
370
- # sample usage
371
- #
372
- # fa = FieldedArray.new %w(zero one two), [0,1,2]
373
- # p fa['zero'] #=> 0
374
- #
375
- #
376
- class FieldedArray
377
- include Fieldable
378
- class << self
379
- def [](*pairs)
380
- pairs.flatten!
381
- raise ArgumentError, "argument must be key/val pairs" unless
382
- (pairs.size % 2 == 0)
383
- fields, elements = [], []
384
- while((f = pairs.shift) and (e = pairs.shift))
385
- fields << f and elements << e
386
- end
387
- new fields, elements
388
- end
389
- end
390
- def initialize fields = [], array = []
391
- @a = array
392
- self.fields = fields
393
- end
394
- def method_missing(meth, *args, &block)
395
- @a.send(meth, *args, &block)
396
- end
397
- delegates =
398
- %w(
399
- to_s
400
- to_str
401
- inspect
402
- )
403
- delegates.each do |meth|
404
- class_eval "def #{ meth }(*a,&b); @a.#{ meth }(*a,&b);end"
405
- end
406
- end
407
- Fieldedarray = FieldedArray
408
-
409
- class PseudoHash < ::Array
410
- class << self
411
- def [](*pairs)
412
- pairs.flatten!
413
- raise ArgumentError, "argument must be key/val pairs" unless
414
- (pairs.size % 2 == 0 and pairs.size >= 2)
415
- keys, values = [], []
416
- while((k = pairs.shift) and (v = pairs.shift))
417
- keys << k and values << v
418
- end
419
- new keys, values
420
- end
421
- end
422
- def initialize keys = [], values = []
423
- self.fields = keys
424
- self.replace values
425
- end
426
- def to_yaml opts = {}
427
- YAML::quick_emit object_id, opts do |out|
428
- out.map taguri, to_yaml_style do |map|
429
- each_pair{|f,v| map.add f,v}
430
- end
431
- end
432
- end
433
- end
434
- Pseudohash = PseudoHash