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 CHANGED
@@ -3,7 +3,7 @@ Structure
3
3
 
4
4
  Structure is a better Struct.
5
5
 
6
- It does wonders when modeling ephemeral data fed in from an API.
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 :name
42
- key :age, :type => Integer
43
- key :friends, :type => Array, :default => []
44
- key :partner, :type => Structure
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
- Boast ORM-esque association idioms:
57
+ Use ORM-esque association idioms:
58
58
 
59
- p2 = Person.new :name => 'Michel'
60
- p1.friends << p2 # has many
59
+ p2 = Person.new
60
+ p1.friends << p2
61
61
 
62
- p3 = Person.new :name => 'Félix'
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": "Jane","age":null,"friends":[]}]}
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 back into Ruby seamlessly, provided you have the same
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=>"Jane", :age=>nil, :friends=>[#<Person:0x0000010107d030 ...>]}, @modifiable=true>
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
@@ -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, JSON, Pathname,
19
- # String, or URI. If not specified, type defaults to String.
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
- modifiable[name] = value.nil? ? nil : typecast.call(value)
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
@@ -1,3 +1,3 @@
1
1
  class Structure
2
- VERSION = '0.5.0'
2
+ VERSION = '0.6.0'
3
3
  end
@@ -1,5 +1,5 @@
1
1
  class Person < Structure
2
2
  key :name
3
3
  key :age, :type => Integer
4
- key :friends, :type => Array, :default => []
4
+ has_many :friends
5
5
  end
@@ -154,7 +154,7 @@ describe Structure do
154
154
 
155
155
  context "when type is Structure" do
156
156
  before(:all) do
157
- Person.key :father, :type => Structure
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
- - 5
7
+ - 6
8
8
  - 0
9
- version: 0.5.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-27 00:00:00 +01:00
17
+ date: 2011-05-28 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency