storable 0.7.4 → 0.8.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.
- data/CHANGES.txt +10 -0
- data/README.rdoc +25 -8
- data/lib/storable.rb +74 -33
- data/storable.gemspec +1 -1
- metadata +17 -5
data/CHANGES.txt
CHANGED
@@ -3,6 +3,16 @@ STORABLE, CHANGES
|
|
3
3
|
* TODO: Handle nested hashes and arrays.
|
4
4
|
* TODO: to_xml, see: http://codeforpeople.com/lib/ruby/xx/xx-2.0.0/README
|
5
5
|
|
6
|
+
#### 0.8.0 (2010-07-28) #############################
|
7
|
+
|
8
|
+
* FIXED: from_delimited now gracefully handles String input by splitting it by $/
|
9
|
+
* CHANGE: Removed field name magic from from_delimited
|
10
|
+
* CHANGE: Converted to Tryouts 2
|
11
|
+
* ADDED: Support for sensitive fields
|
12
|
+
* ADDED: Supports inheritance
|
13
|
+
* ADDED: Storable#to_array
|
14
|
+
|
15
|
+
|
6
16
|
#### 0.7.4 (2010-05-01) #############################
|
7
17
|
|
8
18
|
* FIXED: Check separately if getter and setter methods are already defined
|
data/README.rdoc
CHANGED
@@ -26,6 +26,23 @@ Marshal Ruby classes into and out of multiple formats (yaml, json, csv, tsv)
|
|
26
26
|
puts mac2.position.class # => Fixnum
|
27
27
|
|
28
28
|
|
29
|
+
== Sensitive Fields
|
30
|
+
|
31
|
+
require 'storable'
|
32
|
+
|
33
|
+
class Calc < Storable
|
34
|
+
field :three
|
35
|
+
field :two
|
36
|
+
field :one
|
37
|
+
sensitive_fields :three
|
38
|
+
end
|
39
|
+
|
40
|
+
calc = Calc.new 3, 2, 1
|
41
|
+
calc.to_a # => [3, 2, 1]
|
42
|
+
calc.sensitive!
|
43
|
+
calc.to_a # => [2, 1]
|
44
|
+
|
45
|
+
|
29
46
|
== Storing Procs
|
30
47
|
|
31
48
|
Storable can also marshal Proc objects to and from their actual source code.
|
@@ -38,18 +55,18 @@ Storable can also marshal Proc objects to and from their actual source code.
|
|
38
55
|
field :calculate => Proc
|
39
56
|
end
|
40
57
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
mat1.calculate.source # => "{ @x * @y }"
|
45
|
-
mat1.call :calculate # => 6.0
|
58
|
+
m1 = Maths.new 2.0, 3.0
|
59
|
+
m1.calculate = Proc.new { @x * @y }
|
46
60
|
|
47
|
-
|
61
|
+
m1.calculate.source # => "{ @x * @y }"
|
62
|
+
m1.call :calculate # => 6.0
|
48
63
|
|
49
|
-
|
50
|
-
mat2.call :calculate # => 6.0
|
64
|
+
dump = m1.to_json
|
51
65
|
|
66
|
+
m2 = Maths.from_json dump
|
67
|
+
m2.call :calculate # => 6.0
|
52
68
|
|
69
|
+
|
53
70
|
Anything is possible when you keep your mind open and you use Ruby.
|
54
71
|
|
55
72
|
|
data/lib/storable.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#--
|
2
2
|
# TODO: Handle nested hashes and arrays.
|
3
3
|
# TODO: to_xml, see: http://codeforpeople.com/lib/ruby/xx/xx-2.0.0/README
|
4
|
+
# TODO: from_args([HASH or ordered params])
|
4
5
|
#++
|
5
6
|
|
6
7
|
|
@@ -39,32 +40,25 @@ class Storable
|
|
39
40
|
require 'proc_source'
|
40
41
|
require 'storable/orderedhash' if USE_ORDERED_HASH
|
41
42
|
unless defined?(SUPPORTED_FORMATS) # We can assume all are defined
|
42
|
-
VERSION = "0.
|
43
|
+
VERSION = "0.8.0"
|
43
44
|
NICE_TIME_FORMAT = "%Y-%m-%d@%H:%M:%S".freeze
|
44
45
|
SUPPORTED_FORMATS = [:tsv, :csv, :yaml, :json, :s, :string].freeze
|
45
46
|
end
|
46
47
|
|
47
48
|
@debug = false
|
48
49
|
class << self
|
49
|
-
attr_accessor :field_names, :field_types, :debug
|
50
|
+
attr_accessor :sensitive_fields, :field_names, :field_types, :debug
|
50
51
|
end
|
51
52
|
|
52
|
-
#
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
end
|
62
|
-
|
63
|
-
def postprocess
|
64
|
-
end
|
65
|
-
|
66
|
-
# TODO: from_args([HASH or ordered params])
|
67
|
-
|
53
|
+
# Passes along fields to inherited classes
|
54
|
+
def self.inherited(obj)
|
55
|
+
unless Storable == self
|
56
|
+
obj.sensitive_fields = self.sensitive_fields.clone if !self.sensitive_fields.nil?
|
57
|
+
obj.field_names = self.field_names.clone if !self.field_names.nil?
|
58
|
+
obj.field_types = self.field_types.clone if !self.field_types.nil?
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
68
62
|
# Accepts field definitions in the one of the follow formats:
|
69
63
|
#
|
70
64
|
# field :product
|
@@ -80,10 +74,10 @@ class Storable
|
|
80
74
|
def self.field(args={}, &processor)
|
81
75
|
# TODO: Examine casting from: http://codeforpeople.com/lib/ruby/fattr/fattr-1.0.3/
|
82
76
|
args = {args => nil} unless args.kind_of?(Hash)
|
83
|
-
|
77
|
+
|
78
|
+
self.field_names ||= []
|
79
|
+
self.field_types ||= {}
|
84
80
|
args.each_pair do |m,t|
|
85
|
-
self.field_names ||= []
|
86
|
-
self.field_types ||= {}
|
87
81
|
self.field_names << m
|
88
82
|
self.field_types[m] = t unless t.nil?
|
89
83
|
|
@@ -113,6 +107,17 @@ class Storable
|
|
113
107
|
end
|
114
108
|
end
|
115
109
|
|
110
|
+
def self.sensitive_fields(*args)
|
111
|
+
@sensitive_fields ||= []
|
112
|
+
@sensitive_fields.push *args unless args.empty?
|
113
|
+
@sensitive_fields
|
114
|
+
end
|
115
|
+
|
116
|
+
def self.sensitive_field?(name)
|
117
|
+
@sensitive_fields ||= []
|
118
|
+
@sensitive_fields.member?(name)
|
119
|
+
end
|
120
|
+
|
116
121
|
def self.has_field?(n)
|
117
122
|
field_names.member? n.to_sym
|
118
123
|
end
|
@@ -120,6 +125,11 @@ class Storable
|
|
120
125
|
self.class.field_names.member? n.to_sym
|
121
126
|
end
|
122
127
|
|
128
|
+
|
129
|
+
# This value will be used as a default unless provided on-the-fly.
|
130
|
+
# See SUPPORTED_FORMATS for available values.
|
131
|
+
attr_reader :format
|
132
|
+
|
123
133
|
# +args+ is a list of values to set amongst the fields.
|
124
134
|
# It's assumed that the order values matches the order
|
125
135
|
def initialize(*args)
|
@@ -129,7 +139,25 @@ class Storable
|
|
129
139
|
end
|
130
140
|
preprocess if respond_to?(:preprocess)
|
131
141
|
end
|
132
|
-
|
142
|
+
|
143
|
+
# See SUPPORTED_FORMATS for available values
|
144
|
+
def format=(v)
|
145
|
+
v &&= v.to_sym
|
146
|
+
raise "Unsupported format: #{v}" unless SUPPORTED_FORMATS.member?(v)
|
147
|
+
@format = v
|
148
|
+
end
|
149
|
+
|
150
|
+
def postprocess
|
151
|
+
end
|
152
|
+
|
153
|
+
def sensitive?
|
154
|
+
@storable_sensitive == true
|
155
|
+
end
|
156
|
+
|
157
|
+
def sensitive!
|
158
|
+
@storable_sensitive = true
|
159
|
+
end
|
160
|
+
|
133
161
|
# Returns an array of field names defined by self.field
|
134
162
|
def field_names
|
135
163
|
self.class.field_names
|
@@ -139,7 +167,10 @@ class Storable
|
|
139
167
|
def field_types
|
140
168
|
self.class.field_types
|
141
169
|
end
|
142
|
-
|
170
|
+
def sensitive_fields
|
171
|
+
self.class.sensitive_fields
|
172
|
+
end
|
173
|
+
|
143
174
|
# Dump the object data to the given format.
|
144
175
|
def dump(format=nil, with_titles=false)
|
145
176
|
format &&= format.to_sym
|
@@ -149,6 +180,7 @@ class Storable
|
|
149
180
|
end
|
150
181
|
|
151
182
|
def to_string(*args)
|
183
|
+
# TODO: sensitive?
|
152
184
|
to_s(*args)
|
153
185
|
end
|
154
186
|
|
@@ -251,11 +283,13 @@ class Storable
|
|
251
283
|
self.postprocess
|
252
284
|
self
|
253
285
|
end
|
286
|
+
|
254
287
|
# Return the object data as a hash
|
255
288
|
# +with_titles+ is ignored.
|
256
289
|
def to_hash
|
257
290
|
tmp = USE_ORDERED_HASH ? Storable::OrderedHash.new : {}
|
258
291
|
field_names.each do |fname|
|
292
|
+
next if sensitive? && self.class.sensitive_field?(fname)
|
259
293
|
v = self.send(fname)
|
260
294
|
v = process(fname, v) if has_processor?(fname)
|
261
295
|
if Array === v
|
@@ -265,10 +299,23 @@ class Storable
|
|
265
299
|
end
|
266
300
|
tmp
|
267
301
|
end
|
302
|
+
|
303
|
+
def to_array
|
304
|
+
fields = sensitive? ? (field_names-sensitive_fields) : field_names
|
305
|
+
fields.collect do |fname|
|
306
|
+
next if sensitive? && self.class.sensitive_field?(fname)
|
307
|
+
v = self.send(fname)
|
308
|
+
v = process(fname, v) if has_processor?(fname)
|
309
|
+
if Array === v
|
310
|
+
v = v.collect { |v2| v2.kind_of?(Storable) ? v2.to_a : v2 }
|
311
|
+
end
|
312
|
+
v
|
313
|
+
end
|
314
|
+
end
|
268
315
|
|
269
316
|
def to_json(*from, &blk)
|
270
317
|
hash = to_hash
|
271
|
-
if YAJL_LOADED
|
318
|
+
if YAJL_LOADED # set by Storable
|
272
319
|
ret = Yajl::Encoder.encode(hash)
|
273
320
|
#raise "DELANO"
|
274
321
|
#ret.force_encoding("ISO-8859-1")
|
@@ -361,17 +408,11 @@ class Storable
|
|
361
408
|
# +delim+ is the field delimiter.
|
362
409
|
def self.from_delimited(from=[],delim=',')
|
363
410
|
return if from.empty?
|
364
|
-
|
411
|
+
from = from.split($/) if String === from
|
365
412
|
hash = {}
|
366
413
|
|
367
|
-
fnames =
|
368
|
-
|
369
|
-
fnames = from[0].chomp.split(delim)
|
370
|
-
values = from[1].chomp.split(delim)
|
371
|
-
else
|
372
|
-
fnames = self.field_names
|
373
|
-
values = from[0].chomp.split(delim)
|
374
|
-
end
|
414
|
+
fnames = self.field_names
|
415
|
+
values = from[0].chomp.split(delim)
|
375
416
|
|
376
417
|
fnames.each_with_index do |key,index|
|
377
418
|
next unless values[index]
|
data/storable.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
@spec = Gem::Specification.new do |s|
|
2
2
|
s.name = "storable"
|
3
3
|
s.rubyforge_project = "storable"
|
4
|
-
s.version = "0.
|
4
|
+
s.version = "0.8.0"
|
5
5
|
s.summary = "Storable: Marshal Ruby classes into and out of multiple formats (yaml, json, csv, tsv)"
|
6
6
|
s.description = s.summary
|
7
7
|
s.author = "Delano Mandelbaum"
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: storable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 63
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 8
|
9
|
+
- 0
|
10
|
+
version: 0.8.0
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Delano Mandelbaum
|
@@ -9,7 +15,7 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date: 2010-
|
18
|
+
date: 2010-07-28 00:00:00 -04:00
|
13
19
|
default_executable:
|
14
20
|
dependencies: []
|
15
21
|
|
@@ -45,21 +51,27 @@ rdoc_options:
|
|
45
51
|
require_paths:
|
46
52
|
- lib
|
47
53
|
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
48
55
|
requirements:
|
49
56
|
- - ">="
|
50
57
|
- !ruby/object:Gem::Version
|
58
|
+
hash: 3
|
59
|
+
segments:
|
60
|
+
- 0
|
51
61
|
version: "0"
|
52
|
-
version:
|
53
62
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
54
64
|
requirements:
|
55
65
|
- - ">="
|
56
66
|
- !ruby/object:Gem::Version
|
67
|
+
hash: 3
|
68
|
+
segments:
|
69
|
+
- 0
|
57
70
|
version: "0"
|
58
|
-
version:
|
59
71
|
requirements: []
|
60
72
|
|
61
73
|
rubyforge_project: storable
|
62
|
-
rubygems_version: 1.3.
|
74
|
+
rubygems_version: 1.3.7
|
63
75
|
signing_key:
|
64
76
|
specification_version: 3
|
65
77
|
summary: "Storable: Marshal Ruby classes into and out of multiple formats (yaml, json, csv, tsv)"
|