bound 0.0.9 → 0.1.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.
- checksums.yaml +4 -4
- data/bound.gemspec +2 -0
- data/lib/bound.rb +179 -59
- data/lib/bound/version.rb +1 -1
- data/spec/bound_spec.rb +48 -33
- data/spec/spec_helper.rb +5 -0
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 73b43370b97701af8bc883f5d99ce0ccea3b69ff
|
4
|
+
data.tar.gz: 89d1eb9d1131a6162d3dcf6926839051752a654c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44ca00d9fe5935c8c38050b8f6486e31e662593633214b935949d322b5d2ca21e9095c2a571defb2574b516d98f80b700f14ac0c4827355993444b9acb501f31
|
7
|
+
data.tar.gz: 325cd7b686ec4f7e65821c087a7a8229a02e82a22518b6ac21d5db2813213030eced4b8d13f09ded4635aeea2b63107656f069183ce6860baeb263a7ca31fe30
|
data/bound.gemspec
CHANGED
data/lib/bound.rb
CHANGED
@@ -13,6 +13,16 @@ class Bound
|
|
13
13
|
new_bound_class.optional(*args)
|
14
14
|
end
|
15
15
|
|
16
|
+
def self.required(*args)
|
17
|
+
bound = new_bound_class
|
18
|
+
|
19
|
+
if args.last.kind_of? Hash
|
20
|
+
bound.nested(args.pop)
|
21
|
+
end
|
22
|
+
|
23
|
+
bound.set_attributes(*args)
|
24
|
+
end
|
25
|
+
|
16
26
|
private
|
17
27
|
|
18
28
|
def self.new_bound_class
|
@@ -22,13 +32,97 @@ class Bound
|
|
22
32
|
end
|
23
33
|
|
24
34
|
class BoundClass
|
35
|
+
class Attribute
|
36
|
+
attr_reader :name, :value
|
37
|
+
attr_accessor :nested_class
|
38
|
+
|
39
|
+
def initialize(name)
|
40
|
+
@name = name
|
41
|
+
end
|
42
|
+
|
43
|
+
def assign(value)
|
44
|
+
@assigned = true
|
45
|
+
if nested_class
|
46
|
+
@value = assign_nested(value)
|
47
|
+
else
|
48
|
+
@value = value
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def assign_nested(value)
|
53
|
+
nested_attribute = NestedAttribute.new(nested_class)
|
54
|
+
nested_attribute.resolve(value)
|
55
|
+
end
|
56
|
+
|
57
|
+
def call_on(object)
|
58
|
+
object.public_send @name
|
59
|
+
end
|
60
|
+
|
61
|
+
def valid?
|
62
|
+
!required? || is_assigned?
|
63
|
+
end
|
64
|
+
|
65
|
+
def required?
|
66
|
+
false
|
67
|
+
end
|
68
|
+
|
69
|
+
def is_assigned?
|
70
|
+
!!@assigned
|
71
|
+
end
|
72
|
+
|
73
|
+
def inspect
|
74
|
+
"#{@name}=#{@value.inspect}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class RequiredAttribute < Attribute
|
79
|
+
def required?; true; end
|
80
|
+
end
|
81
|
+
|
82
|
+
class NestedAttribute
|
83
|
+
def initialize(bound_definition)
|
84
|
+
if bound_definition.kind_of?(Array)
|
85
|
+
@assigner = ArrayAssigner.new(bound_definition)
|
86
|
+
else
|
87
|
+
@assigner = ValueAssigner.new(bound_definition)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def resolve(bound_arguments)
|
92
|
+
@assigner.resolve(bound_arguments)
|
93
|
+
end
|
94
|
+
|
95
|
+
class ArrayAssigner
|
96
|
+
def initialize(definitions)
|
97
|
+
@bound_class = definitions.first
|
98
|
+
end
|
99
|
+
|
100
|
+
def resolve(arguments_list)
|
101
|
+
raise ArgumentError.new("Expected #{arguments_list.inspect} to be an array") unless arguments_list.kind_of? Array
|
102
|
+
arguments_list.map do |arguments|
|
103
|
+
@bound_class.new(arguments)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
class ValueAssigner
|
109
|
+
def initialize(definition)
|
110
|
+
@bound_class = definition
|
111
|
+
end
|
112
|
+
|
113
|
+
def resolve(arguments)
|
114
|
+
@bound_class.new(arguments)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
|
25
120
|
class << self
|
26
|
-
attr_accessor :
|
121
|
+
attr_accessor :attrs, :nested_attr_classes
|
27
122
|
|
28
123
|
def initialize_values
|
29
|
-
self.
|
30
|
-
self.
|
31
|
-
self.nested_attributes = []
|
124
|
+
self.attrs = {}
|
125
|
+
self.nested_attr_classes = {}
|
32
126
|
end
|
33
127
|
|
34
128
|
def set_attributes(*attributes)
|
@@ -36,8 +130,11 @@ class Bound
|
|
36
130
|
raise ArgumentError.new("Invalid list of attributes: #{attributes.inspect}")
|
37
131
|
end
|
38
132
|
|
39
|
-
|
40
|
-
|
133
|
+
attributes.each do |attribute|
|
134
|
+
self.attrs[attribute] = RequiredAttribute
|
135
|
+
end
|
136
|
+
|
137
|
+
define_attribute_accessors attributes
|
41
138
|
|
42
139
|
self
|
43
140
|
end
|
@@ -47,104 +144,108 @@ class Bound
|
|
47
144
|
raise ArgumentError.new("Invalid list of optional attributes: #{optionals.inspect}")
|
48
145
|
end
|
49
146
|
|
50
|
-
|
51
|
-
|
147
|
+
optionals.each do |attribute|
|
148
|
+
self.attrs[attribute] = Attribute
|
149
|
+
end
|
150
|
+
|
151
|
+
define_attribute_accessors optionals
|
52
152
|
|
53
153
|
self
|
54
154
|
end
|
55
155
|
|
56
156
|
def nested(nested_attributes)
|
57
157
|
attributes = nested_attributes.keys
|
58
|
-
self.nested_attributes += attributes
|
59
|
-
self.attributes += attributes
|
60
|
-
attr_reader *attributes
|
61
158
|
|
62
159
|
attributes.each do |attribute|
|
63
|
-
|
64
|
-
|
65
|
-
value = extract_values_for_nested_attribute(nested_target, initial_values)
|
66
|
-
|
67
|
-
instance_variable_set :"@#{attribute}", value
|
68
|
-
end
|
160
|
+
self.attrs[attribute] = RequiredAttribute
|
161
|
+
self.nested_attr_classes[attribute] = nested_attributes[attribute]
|
69
162
|
end
|
70
163
|
|
164
|
+
define_attribute_accessors attributes
|
165
|
+
|
71
166
|
self
|
72
167
|
end
|
73
168
|
|
74
169
|
alias :build :new
|
170
|
+
|
171
|
+
private
|
172
|
+
|
173
|
+
def define_attribute_accessors(attributes)
|
174
|
+
define_attribute_readers attributes
|
175
|
+
define_attribute_writers attributes
|
176
|
+
end
|
177
|
+
|
178
|
+
def define_attribute_readers(attributes)
|
179
|
+
attributes.each do |attribute|
|
180
|
+
define_method attribute do
|
181
|
+
get_attribute(attribute).value
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def define_attribute_writers(attributes)
|
187
|
+
attributes.each do |attribute|
|
188
|
+
define_method :"#{attribute}=" do |value|
|
189
|
+
get_attribute(attribute).assign value
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
75
193
|
end
|
76
194
|
|
77
195
|
def initialize(hash_or_object = {})
|
78
|
-
|
196
|
+
seed hash_or_object
|
79
197
|
validate!
|
80
|
-
seed
|
81
|
-
end
|
82
|
-
|
83
|
-
def __attributes__
|
84
|
-
self.class.attributes + self.class.optional_attributes
|
85
198
|
end
|
86
199
|
|
200
|
+
|
87
201
|
def method_missing(meth, *args, &blk)
|
88
202
|
attribute = meth.to_s.gsub(/=$/, '')
|
89
203
|
raise ArgumentError.new("Unknown attribute: #{attribute}")
|
90
204
|
end
|
91
205
|
|
92
|
-
def
|
93
|
-
|
94
|
-
|
95
|
-
values = (self.class.attributes + self.class.optional_attributes).map do |attr|
|
96
|
-
"#{attr}=#{public_send(attr).inspect}"
|
206
|
+
def get_attributes
|
207
|
+
self.class.attrs.keys.map do |attribute_name|
|
208
|
+
get_attribute(attribute_name)
|
97
209
|
end
|
210
|
+
end
|
98
211
|
|
99
|
-
|
212
|
+
def __attributes__
|
213
|
+
puts "DEPRECATED: use get_attributes"
|
214
|
+
get_attributes.map(&:name)
|
100
215
|
end
|
101
216
|
|
102
217
|
private
|
103
218
|
|
104
|
-
def
|
105
|
-
|
106
|
-
|
219
|
+
def get_attribute(attribute_name)
|
220
|
+
attribute_class = self.class.attrs[attribute_name]
|
221
|
+
nested_class = self.class.nested_attr_classes[attribute_name]
|
107
222
|
|
108
|
-
|
109
|
-
|
110
|
-
raise ArgumentError.new("Expected #{initial_values.inspect} to be an array") unless initial_values.kind_of? Array
|
223
|
+
var = :"@#{attribute_name}"
|
224
|
+
attribute = instance_variable_get(var)
|
111
225
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
else
|
116
|
-
build_nested_value(nested_target, initial_values)
|
226
|
+
unless attribute
|
227
|
+
attribute = instance_variable_set(var, attribute_class.new(attribute_name))
|
228
|
+
attribute.nested_class = nested_class if nested_class
|
117
229
|
end
|
230
|
+
|
231
|
+
attribute
|
118
232
|
end
|
119
233
|
|
120
234
|
def validate!
|
121
|
-
|
122
|
-
raise ArgumentError.new("Missing attribute: #{attribute}") unless
|
235
|
+
get_attributes.each do |attribute|
|
236
|
+
raise ArgumentError.new("Missing attribute: #{attribute.name}") unless attribute.valid?
|
123
237
|
end
|
124
238
|
end
|
125
239
|
|
126
|
-
def seed
|
127
|
-
HashSeeder.new(self).seed(@hash)
|
128
|
-
end
|
129
|
-
|
130
|
-
def build_hash(hash_or_object)
|
240
|
+
def seed(hash_or_object)
|
131
241
|
case hash_or_object
|
132
242
|
when Hash
|
133
|
-
|
243
|
+
seeder = HashSeeder.new(self)
|
134
244
|
else
|
135
|
-
|
136
|
-
insert_into_hash(self.class.attributes, hash_or_object)
|
137
|
-
insert_into_hash(self.class.optional_attributes, hash_or_object)
|
245
|
+
seeder = ObjectSeeder.new(self)
|
138
246
|
end
|
139
|
-
end
|
140
247
|
|
141
|
-
|
142
|
-
attributes.each_with_object(@hash) do |attr, h|
|
143
|
-
begin
|
144
|
-
h[attr] = object.public_send(attr)
|
145
|
-
rescue NoMethodError
|
146
|
-
end
|
147
|
-
end
|
248
|
+
seeder.seed(hash_or_object)
|
148
249
|
end
|
149
250
|
end
|
150
251
|
|
@@ -159,4 +260,23 @@ class Bound
|
|
159
260
|
end
|
160
261
|
end
|
161
262
|
end
|
263
|
+
|
264
|
+
class ObjectSeeder
|
265
|
+
def initialize(receiver)
|
266
|
+
@receiver = receiver
|
267
|
+
end
|
268
|
+
|
269
|
+
def seed(object)
|
270
|
+
@receiver.get_attributes.each do |attribute|
|
271
|
+
begin
|
272
|
+
value = attribute.call_on(object)
|
273
|
+
rescue NoMethodError => e
|
274
|
+
value = nil
|
275
|
+
raise ArgumentError, "missing #{attribute.name}" if attribute.required?
|
276
|
+
end
|
277
|
+
|
278
|
+
@receiver.public_send "#{attribute.name}=", value
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
162
282
|
end
|
data/lib/bound/version.rb
CHANGED
data/spec/bound_spec.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Bound do
|
4
|
-
User = Bound.
|
4
|
+
User = Bound.required(:name, :age)
|
5
5
|
|
6
6
|
let(:object) { HashObject.new(hash) }
|
7
7
|
let(:hash) { {:name => 'foo', :age => 23} }
|
8
8
|
|
9
9
|
it 'sets all attributes' do
|
10
10
|
[hash, object].each do |subject|
|
11
|
-
user = User.
|
11
|
+
user = User.new(subject)
|
12
12
|
|
13
13
|
assert_equal hash[:name], user.name
|
14
14
|
assert_equal hash[:age], user.age
|
@@ -29,7 +29,7 @@ describe Bound do
|
|
29
29
|
|
30
30
|
[hash, object].each do |subject|
|
31
31
|
exception = assert_raises ArgumentError, subject.inspect do
|
32
|
-
User.
|
32
|
+
User.new(subject)
|
33
33
|
end
|
34
34
|
|
35
35
|
assert_match(/missing.+age/i, exception.message)
|
@@ -40,7 +40,7 @@ describe Bound do
|
|
40
40
|
hash[:age] = nil
|
41
41
|
|
42
42
|
[hash, object].each do |subject|
|
43
|
-
User.
|
43
|
+
User.new(subject)
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -49,37 +49,37 @@ describe Bound do
|
|
49
49
|
subject = hash
|
50
50
|
|
51
51
|
exception = assert_raises ArgumentError, subject.inspect do
|
52
|
-
User.
|
52
|
+
User.new(subject)
|
53
53
|
end
|
54
54
|
|
55
55
|
assert_match(/unknown.+gender/i, exception.message)
|
56
56
|
end
|
57
57
|
|
58
58
|
it 'exposes an attributes method' do
|
59
|
-
user = User.
|
59
|
+
user = User.new(hash)
|
60
60
|
|
61
|
-
assert_equal 2, user.
|
62
|
-
assert_includes user.
|
63
|
-
assert_includes user.
|
61
|
+
assert_equal 2, user.get_attributes.size
|
62
|
+
assert_includes user.get_attributes.map(&:name), :name
|
63
|
+
assert_includes user.get_attributes.map(&:name), :age
|
64
64
|
end
|
65
65
|
|
66
66
|
describe 'wrong initialization' do
|
67
67
|
it 'fails if new is not called with symbols' do
|
68
68
|
assert_raises ArgumentError do
|
69
|
-
Bound.
|
69
|
+
Bound.required(32, "a")
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
73
|
it 'fails if optional is not called with symbols' do
|
74
74
|
assert_raises ArgumentError do
|
75
|
-
Bound.
|
75
|
+
Bound.required(32, "a")
|
76
76
|
end
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
80
|
describe 'inspect' do
|
81
81
|
let(:inspection) { user.inspect }
|
82
|
-
let(:user) { User.
|
82
|
+
let(:user) { User.new(hash) }
|
83
83
|
|
84
84
|
it 'lists all attributes' do
|
85
85
|
assert_match(/name="foo"/, inspection)
|
@@ -94,11 +94,11 @@ describe Bound do
|
|
94
94
|
end
|
95
95
|
|
96
96
|
describe 'optional attributes' do
|
97
|
-
UserWithoutAge = Bound.
|
97
|
+
UserWithoutAge = Bound.required(:name).optional(:age)
|
98
98
|
|
99
99
|
it 'sets optional attributes' do
|
100
100
|
[hash, object].each do |subject|
|
101
|
-
user = UserWithoutAge.
|
101
|
+
user = UserWithoutAge.new(subject)
|
102
102
|
|
103
103
|
assert_equal hash[:age], user.age
|
104
104
|
end
|
@@ -108,7 +108,7 @@ describe Bound do
|
|
108
108
|
hash.delete :age
|
109
109
|
|
110
110
|
[hash, object].each do |subject|
|
111
|
-
UserWithoutAge.
|
111
|
+
UserWithoutAge.new(subject)
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
@@ -116,16 +116,16 @@ describe Bound do
|
|
116
116
|
hash[:age] = nil
|
117
117
|
|
118
118
|
[hash, object].each do |subject|
|
119
|
-
UserWithoutAge.
|
119
|
+
UserWithoutAge.new(subject)
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
123
123
|
it 'are also included in attributes' do
|
124
124
|
user = UserWithoutAge.build(hash)
|
125
125
|
|
126
|
-
assert_equal 2, user.
|
127
|
-
assert_includes user.
|
128
|
-
assert_includes user.
|
126
|
+
assert_equal 2, user.get_attributes.size
|
127
|
+
assert_includes user.get_attributes.map(&:name), :name
|
128
|
+
assert_includes user.get_attributes.map(&:name), :age
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
@@ -135,23 +135,23 @@ describe Bound do
|
|
135
135
|
|
136
136
|
it 'works without attributes' do
|
137
137
|
[hash, object, nil].each do |subject|
|
138
|
-
UserWithoutAttributes.
|
138
|
+
UserWithoutAttributes.new(subject)
|
139
139
|
end
|
140
140
|
end
|
141
141
|
|
142
142
|
it 'works without argument' do
|
143
|
-
UserWithoutAttributes.
|
143
|
+
UserWithoutAttributes.new
|
144
144
|
end
|
145
145
|
end
|
146
146
|
|
147
147
|
describe 'nested attribute' do
|
148
|
-
Company = Bound.
|
149
|
-
EmployedUser = Bound.
|
148
|
+
Company = Bound.required(:name, :address => Bound.required(:street))
|
149
|
+
EmployedUser = Bound.required(:uid, :company => Company)
|
150
150
|
let(:hash) { {:uid => '1', :company => {:name => 'featurepoly', :address => {:street => 'Germany'}}} }
|
151
151
|
|
152
152
|
it 'works with nested attributes' do
|
153
153
|
[hash, object].each do |subject|
|
154
|
-
user = EmployedUser.
|
154
|
+
user = EmployedUser.new(subject)
|
155
155
|
|
156
156
|
assert_equal hash[:uid], user.uid
|
157
157
|
assert_equal hash[:company][:name], user.company.name
|
@@ -161,8 +161,8 @@ describe Bound do
|
|
161
161
|
end
|
162
162
|
|
163
163
|
describe 'array of nested attribute' do
|
164
|
-
Post = Bound.
|
165
|
-
BloggingUser = Bound.
|
164
|
+
Post = Bound.required(:title)
|
165
|
+
BloggingUser = Bound.required(:name, :posts => [Post])
|
166
166
|
let(:hash) do
|
167
167
|
{
|
168
168
|
:name => 'Steve',
|
@@ -175,7 +175,7 @@ describe Bound do
|
|
175
175
|
|
176
176
|
it 'works with array of nested attributes' do
|
177
177
|
[hash, object].each do |subject|
|
178
|
-
user = BloggingUser.
|
178
|
+
user = BloggingUser.new(subject)
|
179
179
|
|
180
180
|
assert_equal hash[:name], user.name
|
181
181
|
assert_equal hash[:posts][0][:title], user.posts[0].title
|
@@ -188,7 +188,7 @@ describe Bound do
|
|
188
188
|
|
189
189
|
[hash, object].each do |subject|
|
190
190
|
exception = assert_raises ArgumentError do
|
191
|
-
BloggingUser.
|
191
|
+
BloggingUser.new(subject)
|
192
192
|
end
|
193
193
|
|
194
194
|
assert_match(/array/i, exception.message)
|
@@ -197,11 +197,11 @@ describe Bound do
|
|
197
197
|
end
|
198
198
|
|
199
199
|
it 'are also included in attributes' do
|
200
|
-
user = BloggingUser.
|
200
|
+
user = BloggingUser.new(hash)
|
201
201
|
|
202
|
-
assert_equal 2, user.
|
203
|
-
assert_includes user.
|
204
|
-
assert_includes user.
|
202
|
+
assert_equal 2, user.get_attributes.size
|
203
|
+
assert_includes user.get_attributes.map(&:name), :name
|
204
|
+
assert_includes user.get_attributes.map(&:name), :posts
|
205
205
|
end
|
206
206
|
end
|
207
207
|
|
@@ -215,11 +215,26 @@ describe Bound do
|
|
215
215
|
end
|
216
216
|
|
217
217
|
describe 'allows nested as constructor' do
|
218
|
-
Car = Bound.
|
218
|
+
Car = Bound.required(:producer => Bound.required(:name))
|
219
219
|
|
220
220
|
it 'works' do
|
221
221
|
assert_raises(ArgumentError) { Car.new }
|
222
222
|
assert_equal "VW", Car.new(:producer => {:name => 'VW'}).producer.name
|
223
223
|
end
|
224
224
|
end
|
225
|
+
|
226
|
+
describe '__attributes__' do
|
227
|
+
DeprecatedUser = Bound.required(:name)
|
228
|
+
|
229
|
+
it 'is deprecated' do
|
230
|
+
user = DeprecatedUser.new(:name => 'foo')
|
231
|
+
|
232
|
+
deprecation_warning, _ = capture_io do
|
233
|
+
user.__attributes__
|
234
|
+
end
|
235
|
+
|
236
|
+
assert_match(/DEPRECATED/, deprecation_warning)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
225
240
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bound
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jakob Holderbaum
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-09-
|
12
|
+
date: 2013-09-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -53,6 +53,20 @@ dependencies:
|
|
53
53
|
- - ~>
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: 5.0.7
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: simplecov
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
56
70
|
description:
|
57
71
|
email:
|
58
72
|
- jh@neopoly.de
|
@@ -92,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
106
|
version: '0'
|
93
107
|
requirements: []
|
94
108
|
rubyforge_project:
|
95
|
-
rubygems_version: 2.0.
|
109
|
+
rubygems_version: 2.0.6
|
96
110
|
signing_key:
|
97
111
|
specification_version: 4
|
98
112
|
summary: Implements a nice helper for fast boundary definitions
|