structure 0.5.0 → 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/README.md +12 -16
- data/lib/structure.rb +17 -12
- data/lib/structure/version.rb +1 -1
- data/spec/models/person.rb +1 -1
- data/spec/structure_spec.rb +1 -13
- metadata +3 -3
data/README.md
CHANGED
|
@@ -3,7 +3,7 @@ Structure
|
|
|
3
3
|
|
|
4
4
|
Structure is a better Struct.
|
|
5
5
|
|
|
6
|
-
It
|
|
6
|
+
It works great when modeling ephemeral data fed in from an API.
|
|
7
7
|
|
|
8
8
|
#_ d
|
|
9
9
|
##_ d#
|
|
@@ -38,10 +38,10 @@ Require:
|
|
|
38
38
|
Define a model:
|
|
39
39
|
|
|
40
40
|
class Person < Structure
|
|
41
|
-
key
|
|
42
|
-
key
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
key :name
|
|
42
|
+
key :age, :type => Integer
|
|
43
|
+
has_many :friends
|
|
44
|
+
has_one :partner
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
Conjure an object:
|
|
@@ -54,27 +54,24 @@ Typecast values:
|
|
|
54
54
|
p1.age
|
|
55
55
|
=> 28
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
Use ORM-esque association idioms:
|
|
58
58
|
|
|
59
|
-
p2 = Person.new
|
|
60
|
-
p1.friends << p2
|
|
59
|
+
p2 = Person.new
|
|
60
|
+
p1.friends << p2
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
p1.partner = p3 # has one
|
|
64
|
-
|
|
65
|
-
Dump good-looking JSON:
|
|
62
|
+
Dump well-structured JSON:
|
|
66
63
|
|
|
67
64
|
require 'structure/json'
|
|
68
65
|
|
|
69
66
|
json = p1.to_json
|
|
70
|
-
=> {"json_class":"Person","name":"John","age":28,"friends":[{"json_class":"Person","name":
|
|
67
|
+
=> {"json_class":"Person","name":"John","age":28,"friends":[{"json_class":"Person","name":null,"age":null,"friends":[]}],"partner":null}
|
|
71
68
|
|
|
72
|
-
Load the JSON elsewhere
|
|
69
|
+
Load the JSON elsewhere into Ruby seamlessly, provided you have the same
|
|
73
70
|
models set up:
|
|
74
71
|
|
|
75
72
|
person = JSON.parse(json)
|
|
76
73
|
person.friends.first
|
|
77
|
-
=> #<Person:0x0000010107d030 @attributes={:name=>
|
|
74
|
+
=> #<Person:0x0000010107d030 @attributes={:name=>nil, :age=>nil, :friends=>[], :partner=>nil}, @modifiable=true>
|
|
78
75
|
|
|
79
76
|
Throw in some Active Model modules...
|
|
80
77
|
|
|
@@ -84,7 +81,6 @@ Throw in some Active Model modules...
|
|
|
84
81
|
include ActiveModel::Validations
|
|
85
82
|
|
|
86
83
|
key :title
|
|
87
|
-
key :authors, :type => Array, :default => []
|
|
88
84
|
|
|
89
85
|
validates_presence_of :title
|
|
90
86
|
end
|
data/lib/structure.rb
CHANGED
|
@@ -11,12 +11,23 @@ class Structure
|
|
|
11
11
|
|
|
12
12
|
TYPES = [Array, Boolean, Float, Hash, Integer, String, Structure]
|
|
13
13
|
|
|
14
|
+
# A shortcut to define an attribute that corresponds to an array of other
|
|
15
|
+
# objects, possibly Structures.
|
|
16
|
+
def self.has_many(name)
|
|
17
|
+
key name, :type => Array, :default => []
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# A shortcut to define an attribute that corresponds to another Structure.
|
|
21
|
+
def self.has_one(name)
|
|
22
|
+
key name, :type => Structure
|
|
23
|
+
end
|
|
24
|
+
|
|
14
25
|
# Defines an attribute key.
|
|
15
26
|
#
|
|
16
27
|
# Takes a name and an optional hash of options. Available options are:
|
|
17
28
|
#
|
|
18
|
-
# * :type, which can be Array, Boolean, Float, Integer,
|
|
19
|
-
#
|
|
29
|
+
# * :type, which can be Array, Boolean, Float, Hash, Integer, String, or
|
|
30
|
+
# Structure. If not specified, type defaults to String.
|
|
20
31
|
# * :default, which sets the default value for the attribute.
|
|
21
32
|
#
|
|
22
33
|
# class Book
|
|
@@ -58,6 +69,9 @@ class Structure
|
|
|
58
69
|
end
|
|
59
70
|
end
|
|
60
71
|
elsif [Hash, Structure].include? type
|
|
72
|
+
|
|
73
|
+
# Raise an exception rather than typecast if type is Hash or
|
|
74
|
+
# Structure.
|
|
61
75
|
lambda do |value|
|
|
62
76
|
unless value.is_a? type
|
|
63
77
|
raise TypeError, "#{value} is not a #{type}"
|
|
@@ -73,7 +87,7 @@ class Structure
|
|
|
73
87
|
|
|
74
88
|
# Define a setter.
|
|
75
89
|
define_method("#{name}=") do |value|
|
|
76
|
-
|
|
90
|
+
@attributes[name] = value.nil? ? nil : typecast.call(value)
|
|
77
91
|
end
|
|
78
92
|
end
|
|
79
93
|
end
|
|
@@ -123,13 +137,4 @@ class Structure
|
|
|
123
137
|
attributes
|
|
124
138
|
end
|
|
125
139
|
end
|
|
126
|
-
|
|
127
|
-
def modifiable
|
|
128
|
-
begin
|
|
129
|
-
@modifiable = true
|
|
130
|
-
rescue
|
|
131
|
-
raise TypeError, "can't modify frozen #{self.class}"
|
|
132
|
-
end
|
|
133
|
-
@attributes
|
|
134
|
-
end
|
|
135
140
|
end
|
data/lib/structure/version.rb
CHANGED
data/spec/models/person.rb
CHANGED
data/spec/structure_spec.rb
CHANGED
|
@@ -154,7 +154,7 @@ describe Structure do
|
|
|
154
154
|
|
|
155
155
|
context "when type is Structure" do
|
|
156
156
|
before(:all) do
|
|
157
|
-
Person.
|
|
157
|
+
Person.has_one :father
|
|
158
158
|
end
|
|
159
159
|
|
|
160
160
|
context "when setting to a value that is not a Structure" do
|
|
@@ -179,18 +179,6 @@ describe Structure do
|
|
|
179
179
|
end
|
|
180
180
|
end
|
|
181
181
|
|
|
182
|
-
context "when frozen" do
|
|
183
|
-
before do
|
|
184
|
-
person.freeze
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
it "raises an error" do
|
|
188
|
-
expect do
|
|
189
|
-
person.name = 'Joe'
|
|
190
|
-
end.to raise_error TypeError
|
|
191
|
-
end
|
|
192
|
-
end
|
|
193
|
-
|
|
194
182
|
context "when setting the value of an attribute to nil" do
|
|
195
183
|
it "does not typecast the value" do
|
|
196
184
|
person.age = nil
|
metadata
CHANGED
|
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
|
4
4
|
prerelease: false
|
|
5
5
|
segments:
|
|
6
6
|
- 0
|
|
7
|
-
-
|
|
7
|
+
- 6
|
|
8
8
|
- 0
|
|
9
|
-
version: 0.
|
|
9
|
+
version: 0.6.0
|
|
10
10
|
platform: ruby
|
|
11
11
|
authors:
|
|
12
12
|
- Paper Cavalier
|
|
@@ -14,7 +14,7 @@ autorequire:
|
|
|
14
14
|
bindir: bin
|
|
15
15
|
cert_chain: []
|
|
16
16
|
|
|
17
|
-
date: 2011-05-
|
|
17
|
+
date: 2011-05-28 00:00:00 +01:00
|
|
18
18
|
default_executable:
|
|
19
19
|
dependencies:
|
|
20
20
|
- !ruby/object:Gem::Dependency
|