storable 0.8.7 → 0.8.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -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