storable 0.8.7 → 0.8.8

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.
@@ -2,7 +2,15 @@ STORABLE, CHANGES
2
2
 
3
3
  * TODO: https://github.com/delano/storable/pull/2
4
4
  * TODO: Handle nested hashes and arrays.
5
- * TODO: to_xml, see: http://codeforpeople.com/lib/ruby/xx/xx-2.0.0/README
5
+
6
+
7
+ #### 0.8.8 (2011-05-20) #############################
8
+
9
+ * ADDED: Storable.field can now take and store Hash options (:default, :meth)
10
+
11
+ #### 0.8.7 (2011-??-??) #############################
12
+
13
+ * ?
6
14
 
7
15
  #### 0.8.6 (2010-12-31) #############################
8
16
 
@@ -41,7 +41,7 @@ end
41
41
  class RubyToken::Token
42
42
 
43
43
  # These EXPR_BEG tokens don't have associated end tags
44
- FAKIES = [RubyToken::TkWHEN, RubyToken::TkELSIF, RubyToken::TkTHEN]
44
+ FAKIES = [RubyToken::TkWHEN, RubyToken::TkELSIF, RubyToken::TkELSE, RubyToken::TkTHEN]
45
45
 
46
46
  def name
47
47
  @name ||= nil
@@ -35,14 +35,14 @@ class Storable
35
35
  require 'proc_source'
36
36
  require 'storable/orderedhash' if USE_ORDERED_HASH
37
37
  unless defined?(SUPPORTED_FORMATS) # We can assume all are defined
38
- VERSION = "0.8.7"
38
+ VERSION = "0.8.8"
39
39
  NICE_TIME_FORMAT = "%Y-%m-%d@%H:%M:%S".freeze
40
40
  SUPPORTED_FORMATS = [:tsv, :csv, :yaml, :json, :s, :string].freeze
41
41
  end
42
42
 
43
43
  @debug = false
44
44
  class << self
45
- attr_accessor :sensitive_fields, :field_names, :field_types, :debug
45
+ attr_accessor :sensitive_fields, :field_names, :field_types, :field_opts, :debug
46
46
  end
47
47
 
48
48
  # Passes along fields to inherited classes
@@ -66,37 +66,61 @@ class Storable
66
66
  # data is available by the standard accessors, class.product and class.product= etc...
67
67
  # The value of the field will be cast to the type (if provided) when read from a file.
68
68
  # The value is not touched when the type is not provided.
69
- def self.field(args={}, &processor)
69
+ def self.field(*args, &processor)
70
70
  # TODO: Examine casting from: http://codeforpeople.com/lib/ruby/fattr/fattr-1.0.3/
71
- args = {args => nil} unless args.kind_of?(Hash)
72
-
71
+ field_definitions = {}
72
+ if args.first.kind_of?(Hash)
73
+ args.first.each_pair do |fname,klass|
74
+ field_definitions[fname] = { :class => klass }
75
+ end
76
+ else
77
+ fname, opts = *args
78
+ if opts.nil?
79
+ field_definitions[fname] = {}
80
+ elsif Hash === opts
81
+ field_definitions[fname] = opts
82
+ else
83
+ raise ArgumentError, "Second argument must be a hash"
84
+ end
85
+ end
86
+
73
87
  self.field_names ||= []
74
88
  self.field_types ||= {}
75
- args.each_pair do |m,t|
76
- self.field_names << m
77
- self.field_types[m] = t unless t.nil?
89
+ self.field_opts ||= {}
90
+ field_definitions.each_pair do |fname,opts|
91
+ self.field_names << fname
92
+ self.field_opts[fname] = opts
93
+ self.field_types[fname] = opts[:class] unless opts[:class].nil?
78
94
 
79
95
  # This processor automatically converts a Proc object
80
96
  # to a String of its source.
81
- processor = proc_processor if t == Proc && processor.nil?
97
+ processor = proc_processor if opts[:class] == Proc && processor.nil?
82
98
 
83
99
  unless processor.nil?
84
- define_method("_storable_processor_#{m}", &processor)
100
+ define_method("_storable_processor_#{fname}", &processor)
85
101
  end
86
102
 
87
- if method_defined?(m) # don't redefine the getter method
88
- STDERR.puts "method exists: #{self}##{m}" if Storable.debug
103
+ if method_defined?(fname) # don't redefine the getter method
104
+ STDERR.puts "method exists: #{self}##{fname}" if Storable.debug
89
105
  else
90
- define_method(m) do
91
- instance_variable_get("@#{m}")
106
+ define_method(fname) do
107
+ ret = instance_variable_get("@#{fname}") || opts[:default]
108
+ if ret.nil?
109
+ if opts[:default]
110
+ ret = opts[:default]
111
+ elsif opts[:meth]
112
+ ret = self.send(opts[:meth])
113
+ end
114
+ end
115
+ ret
92
116
  end
93
117
  end
94
118
 
95
- if method_defined?("#{m}=") # don't redefine the setter methods
96
- STDERR.puts "method exists: #{self}##{m}=" if Storable.debug
119
+ if method_defined?("#{fname}=") # don't redefine the setter methods
120
+ STDERR.puts "method exists: #{self}##{fname}=" if Storable.debug
97
121
  else
98
- define_method("#{m}=") do |val|
99
- instance_variable_set("@#{m}",val)
122
+ define_method("#{fname}=") do |val|
123
+ instance_variable_set("@#{fname}",val)
100
124
  end
101
125
  end
102
126
  end
@@ -145,15 +169,15 @@ class Storable
145
169
 
146
170
  # Returns an array of field names defined by self.field
147
171
  def field_names
148
- self.class.field_names
172
+ self.class.field_names #|| self.class.ancestors.first.field_names
149
173
  end
150
174
  # Returns an array of field types defined by self.field. Fields that did
151
175
  # not receive a type are set to nil.
152
176
  def field_types
153
- self.class.field_types
177
+ self.class.field_types #|| self.class.ancestors.first.field_types
154
178
  end
155
179
  def sensitive_fields
156
- self.class.sensitive_fields
180
+ self.class.sensitive_fields #|| self.class.ancestors.first.sensitive_fields
157
181
  end
158
182
 
159
183
  # Dump the object data to the given format.
@@ -298,14 +322,16 @@ class Storable
298
322
  def to_hash
299
323
  preprocess if respond_to? :preprocess
300
324
  tmp = USE_ORDERED_HASH ? Storable::OrderedHash.new : {}
301
- field_names.each do |fname|
302
- next if sensitive? && self.class.sensitive_field?(fname)
303
- v = self.send(fname)
304
- v = process(fname, v) if has_processor?(fname)
305
- if Array === v
306
- v = v.collect { |v2| v2.kind_of?(Storable) ? v2.to_hash : v2 }
325
+ if field_names
326
+ field_names.each do |fname|
327
+ next if sensitive? && self.class.sensitive_field?(fname)
328
+ v = self.send(fname)
329
+ v = process(fname, v) if has_processor?(fname)
330
+ if Array === v
331
+ v = v.collect { |v2| v2.kind_of?(Storable) ? v2.to_hash : v2 }
332
+ end
333
+ tmp[fname] = v.kind_of?(Storable) ? v.to_hash : v
307
334
  end
308
- tmp[fname] = v.kind_of?(Storable) ? v.to_hash : v
309
335
  end
310
336
  tmp
311
337
  end
@@ -329,9 +355,6 @@ class Storable
329
355
  hash = to_hash
330
356
  if YAJL_LOADED # set by Storable
331
357
  ret = Yajl::Encoder.encode(hash)
332
- #raise "DELANO"
333
- #ret.force_encoding("ISO-8859-1")
334
- #p [:to, ret.encoding.name] if ret.respond_to?(:encoding)
335
358
  ret
336
359
  elsif JSON_LOADED
337
360
  JSON.generate(hash, *from, &blk)
@@ -508,7 +531,8 @@ class Storable
508
531
  end
509
532
  def proc_processor
510
533
  Proc.new do |val|
511
- (Proc === val) ? val.source : val
534
+ ret = (Proc === val) ? val.source : val
535
+ ret
512
536
  end
513
537
  end
514
538
  # If the object already has a value for +@id+
@@ -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.8.7"
4
+ s.version = "0.8.8"
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
@@ -2,7 +2,7 @@
2
2
  name: storable
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.8.7
5
+ version: 0.8.8
6
6
  platform: ruby
7
7
  authors:
8
8
  - Delano Mandelbaum
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-03-03 00:00:00 -05:00
13
+ date: 2011-05-20 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies: []
16
16