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.
Files changed (5) hide show
  1. data/CHANGES.txt +10 -0
  2. data/README.rdoc +25 -8
  3. data/lib/storable.rb +74 -33
  4. data/storable.gemspec +1 -1
  5. 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
- mat1 = Maths.new 2.0, 3.0
42
- mat1.calculate = Proc.new { @x * @y }
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
- dump = mat1.to_json
61
+ m1.calculate.source # => "{ @x * @y }"
62
+ m1.call :calculate # => 6.0
48
63
 
49
- mat2 = Maths.from_json dump
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.7.4"
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
- # This value will be used as a default unless provided on-the-fly.
53
- # See SUPPORTED_FORMATS for available values.
54
- attr_reader :format
55
-
56
- # See SUPPORTED_FORMATS for available values
57
- def format=(v)
58
- v &&= v.to_sym
59
- raise "Unsupported format: #{v}" unless SUPPORTED_FORMATS.member?(v)
60
- @format = v
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
- # We grab an instance of the class so we can
411
+ from = from.split($/) if String === from
365
412
  hash = {}
366
413
 
367
- fnames = values = []
368
- if (from.size > 1 && !from[1].empty?)
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.7.4"
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
- version: 0.7.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-05-01 00:00:00 -04:00
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.5
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)"