storable 0.5.8 → 0.6.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 +6 -0
- data/lib/storable.rb +62 -27
- data/storable.gemspec +1 -1
- metadata +3 -3
data/CHANGES.txt
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
STORABLE, CHANGES
|
2
2
|
|
3
|
+
#### 0.6.0 (2009-11-27) #############################
|
4
|
+
|
5
|
+
* FIXED: Undefined @@field_names error when no fields specified
|
6
|
+
* ADDED: Support for field output processors
|
7
|
+
* ADDED: Storable::DefaultProcessors
|
8
|
+
|
3
9
|
|
4
10
|
#### 0.5.8 (2009-10-06) #############################
|
5
11
|
|
data/lib/storable.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
#++
|
5
5
|
|
6
6
|
|
7
|
-
USE_ORDERED_HASH = (RUBY_VERSION =~
|
7
|
+
USE_ORDERED_HASH = (RUBY_VERSION =~ /^1.9/).nil?
|
8
8
|
|
9
9
|
begin
|
10
10
|
require 'json'
|
@@ -15,19 +15,40 @@ end
|
|
15
15
|
require 'yaml'
|
16
16
|
require 'fileutils'
|
17
17
|
require 'time'
|
18
|
-
|
18
|
+
|
19
|
+
|
20
|
+
class Storable
|
21
|
+
module DefaultProcessors
|
22
|
+
def hash_proc_processor
|
23
|
+
Proc.new do |procs|
|
24
|
+
a = {}
|
25
|
+
procs.each_pair { |n,v|
|
26
|
+
a[n] = (Proc === v) ? v.source : v
|
27
|
+
}
|
28
|
+
a
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
19
34
|
# Storable makes data available in multiple formats and can
|
20
35
|
# re-create objects from files. Fields are defined using the
|
21
36
|
# Storable.field method which tells Storable the order and
|
22
37
|
# name.
|
23
38
|
class Storable
|
39
|
+
extend Storable::DefaultProcessors
|
40
|
+
|
24
41
|
require 'storable/orderedhash' if USE_ORDERED_HASH
|
25
42
|
unless defined?(SUPPORTED_FORMATS) # We can assume all are defined
|
26
|
-
VERSION = "0.
|
43
|
+
VERSION = "0.6.0"
|
27
44
|
NICE_TIME_FORMAT = "%Y-%m-%d@%H:%M:%S".freeze
|
28
45
|
SUPPORTED_FORMATS = [:tsv, :csv, :yaml, :json, :s, :string].freeze
|
29
46
|
end
|
30
47
|
|
48
|
+
class << self
|
49
|
+
attr_accessor :field_names, :field_types
|
50
|
+
end
|
51
|
+
|
31
52
|
# This value will be used as a default unless provided on-the-fly.
|
32
53
|
# See SUPPORTED_FORMATS for available values.
|
33
54
|
attr_reader :format
|
@@ -48,23 +69,29 @@ class Storable
|
|
48
69
|
#
|
49
70
|
# field :product
|
50
71
|
# field :product => Integer
|
72
|
+
# field :product do |val|
|
73
|
+
# # modify val before it's stored.
|
74
|
+
# end
|
51
75
|
#
|
52
76
|
# The order they're defined determines the order the will be output. The fields
|
53
77
|
# data is available by the standard accessors, class.product and class.product= etc...
|
54
78
|
# The value of the field will be cast to the type (if provided) when read from a file.
|
55
79
|
# The value is not touched when the type is not provided.
|
56
|
-
def self.field(args={})
|
80
|
+
def self.field(args={}, &processor)
|
57
81
|
# TODO: Examine casting from: http://codeforpeople.com/lib/ruby/fattr/fattr-1.0.3/
|
58
82
|
args = {args => nil} unless args.kind_of?(Hash)
|
59
83
|
|
60
84
|
args.each_pair do |m,t|
|
85
|
+
self.field_names ||= []
|
86
|
+
self.field_types ||= []
|
87
|
+
self.field_names << m
|
88
|
+
self.field_types << t unless t.nil?
|
61
89
|
|
62
|
-
|
63
|
-
|
64
|
-
class_variable_set(tuple[0], class_variable_get(tuple[0]) << tuple[1])
|
90
|
+
unless processor.nil?
|
91
|
+
define_method("_storable_processor_#{m}", &processor)
|
65
92
|
end
|
66
93
|
|
67
|
-
next if method_defined?(m)
|
94
|
+
next if method_defined?(m) # don't refine the accessor methods
|
68
95
|
|
69
96
|
define_method(m) do instance_variable_get("@#{m}") end
|
70
97
|
define_method("#{m}=") do |val|
|
@@ -80,23 +107,15 @@ class Storable
|
|
80
107
|
self.class.field_names.member? n.to_sym
|
81
108
|
end
|
82
109
|
|
83
|
-
|
84
|
-
def self.field_names
|
85
|
-
class_variable_get(:@@field_names)
|
86
|
-
end
|
110
|
+
|
87
111
|
# Returns an array of field names defined by self.field
|
88
112
|
def field_names
|
89
|
-
self.class.
|
90
|
-
end
|
91
|
-
# Returns an array of field types defined by self.field. Fields that did
|
92
|
-
# not receive a type are set to nil.
|
93
|
-
def self.field_types
|
94
|
-
class_variable_get(:@@field_types)
|
113
|
+
self.class.field_names
|
95
114
|
end
|
96
115
|
# Returns an array of field types defined by self.field. Fields that did
|
97
116
|
# not receive a type are set to nil.
|
98
117
|
def field_types
|
99
|
-
self.class.
|
118
|
+
self.class.field_types
|
100
119
|
end
|
101
120
|
|
102
121
|
# Dump the object data to the given format.
|
@@ -185,22 +204,40 @@ class Storable
|
|
185
204
|
def to_hash
|
186
205
|
tmp = USE_ORDERED_HASH ? Storable::OrderedHash.new : {}
|
187
206
|
field_names.each do |fname|
|
188
|
-
|
207
|
+
v = self.send(fname)
|
208
|
+
v = process(fname, v) if has_processor?(fname)
|
209
|
+
if Array === v
|
210
|
+
v = v.collect { |v2| v2.kind_of?(Storable) ? v2.to_hash : v2 }
|
211
|
+
end
|
212
|
+
tmp[fname] = v.kind_of?(Storable) ? v.to_hash : v
|
189
213
|
end
|
190
214
|
tmp
|
191
215
|
end
|
192
216
|
|
217
|
+
def to_json(*from, &blk)
|
218
|
+
to_hash.to_json(*from, &blk)
|
219
|
+
end
|
220
|
+
|
221
|
+
def to_yaml(*from, &blk)
|
222
|
+
to_hash.to_yaml(*from, &blk)
|
223
|
+
end
|
224
|
+
|
225
|
+
def process(fname, val)
|
226
|
+
self.send :"_storable_processor_#{fname}", val
|
227
|
+
end
|
228
|
+
|
229
|
+
def has_processor?(fname)
|
230
|
+
self.respond_to? :"_storable_processor_#{fname}"
|
231
|
+
end
|
232
|
+
|
193
233
|
# Create a new instance of the object from YAML.
|
194
234
|
# +from+ a YAML String or Array (split into by line).
|
195
235
|
def self.from_yaml(*from)
|
196
236
|
from_str = [from].flatten.compact.join('')
|
197
237
|
hash = YAML::load(from_str)
|
198
|
-
hash = from_hash(hash) if hash
|
238
|
+
hash = from_hash(hash) if Hash === hash
|
199
239
|
hash
|
200
240
|
end
|
201
|
-
def to_yaml
|
202
|
-
to_hash.to_yaml
|
203
|
-
end
|
204
241
|
|
205
242
|
# Create a new instance of the object from a JSON string.
|
206
243
|
# +from+ a YAML String or Array (split into by line).
|
@@ -214,9 +251,6 @@ class Storable
|
|
214
251
|
hash_sym = from_hash(hash_sym) if hash_sym.kind_of?(Hash)
|
215
252
|
hash_sym
|
216
253
|
end
|
217
|
-
def to_json(with_titles=true)
|
218
|
-
to_hash.to_json
|
219
|
-
end
|
220
254
|
|
221
255
|
# Return the object data as a delimited string.
|
222
256
|
# +with_titles+ specifiy whether to include field names (default: false)
|
@@ -307,3 +341,4 @@ class Storable
|
|
307
341
|
end
|
308
342
|
end
|
309
343
|
|
344
|
+
|
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.6.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,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: storable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Delano Mandelbaum
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-11-27 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -58,7 +58,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
58
58
|
requirements: []
|
59
59
|
|
60
60
|
rubyforge_project: storable
|
61
|
-
rubygems_version: 1.3.
|
61
|
+
rubygems_version: 1.3.5
|
62
62
|
signing_key:
|
63
63
|
specification_version: 3
|
64
64
|
summary: "Storable: Marshal Ruby classes into and out of multiple formats (yaml, json, csv, tsv)"
|