bound 1.0.1 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 40eb13fe1d57fd0d42c0d0fc5c91348173071cb2
4
- data.tar.gz: 61658fd50d9bf0dd3790b75bca0588e80863ca4f
3
+ metadata.gz: cc2a2abb3f5f3cec8ad904ad037dfbbbf77d3b7d
4
+ data.tar.gz: c1d7bc7dc181231fa857fd2ac0749bea48fb6488
5
5
  SHA512:
6
- metadata.gz: 86f3b026b006ff92b6652cd3e37df15206bcb304150c4d9c3c0fee70809b02a65fce814f67dc92f40e4df87ef93e351b182420e38d968e8c8cac27e8fbe8b9c5
7
- data.tar.gz: ebc0035cc9f636a9af6f798a3cb70ab0420834f73b8212b2f42d74b640217a6ebb5385b7e3e98830c42f6cbe0282757f2839e55a44d0c55b4d0167437177afd7
6
+ metadata.gz: 66cea5184ddda962bbb0ae8b2cc19e23075f1f01e03991e6b5b37819362d2b24dca324a62f218b36b45a55eb1493c93a73c3424d119780d66bc3f896856fc928
7
+ data.tar.gz: d9c232a68c91b193165ae4d8980e535b574560bb03435da1326a360bd305a2de7339b3a67b2b3cf60f894a740ca4b4472815f0699357a34a74c611a6ea0b7cd5
@@ -1,4 +1,5 @@
1
1
  require "bound/version"
2
+ require "bound/caller"
2
3
 
3
4
  class Bound
4
5
  def self.new(*args)
@@ -23,8 +24,6 @@ class Bound
23
24
 
24
25
  class BoundClass
25
26
  class Attribute
26
- NotImplemented = Class.new(RuntimeError)
27
-
28
27
  attr_reader :name, :value
29
28
  attr_accessor :nested_class
30
29
 
@@ -47,12 +46,7 @@ class Bound
47
46
  end
48
47
 
49
48
  def call_on(object)
50
- method = @name
51
- if object.respond_to?(method)
52
- object.send method
53
- else
54
- raise NotImplemented, "undefined method `#{method}' for #{object}"
55
- end
49
+ Caller.call(object, @name)
56
50
  end
57
51
 
58
52
  def valid?
@@ -155,20 +149,22 @@ class Bound
155
149
  raise ArgumentError.new("Invalid list of attributes: #{attributes.inspect}")
156
150
  end
157
151
 
152
+ attribute_class = if is_optional
153
+ Attribute
154
+ else
155
+ RequiredAttribute
156
+ end
157
+
158
158
  attributes.each do |attribute|
159
- if is_optional
160
- self.attrs[attribute] = Attribute
161
- else
162
- self.attrs[attribute] = RequiredAttribute
163
- end
159
+ self.attrs[attribute] = attribute_class
164
160
  end
165
161
 
166
162
  define_attribute_accessors attributes
167
163
 
168
164
  if nested_attributes.any?
169
165
  set_attributes flag, nested_attributes.keys
170
- nested_attributes.each do |attribute_name, attribute_class|
171
- self.nested_attr_classes[attribute_name] = attribute_class
166
+ nested_attributes.each do |attribute_name, nested_class|
167
+ self.nested_attr_classes[attribute_name] = nested_class
172
168
  end
173
169
  end
174
170
  end
@@ -195,15 +191,14 @@ class Bound
195
191
  end
196
192
  end
197
193
 
198
- def initialize(*seeds)
194
+ def initialize(seed = nil, overwrite = nil)
199
195
  @attributes = {}
200
- seeds.reverse.each do |seed|
201
- seed_with seed
202
- end
196
+ raise('Overwrite with object') if overwrite && !overwrite.kind_of?(Hash)
197
+ seed_with overwrite if overwrite
198
+ seed_with seed if seed
203
199
  validate!
204
200
  end
205
201
 
206
-
207
202
  def method_missing(meth, *args, &blk)
208
203
  attribute = meth.to_s.gsub(/=$/, '')
209
204
  raise ArgumentError.new("Unknown attribute: #{self.class}##{attribute}")
@@ -225,27 +220,24 @@ class Bound
225
220
  end
226
221
 
227
222
  def get_attribute(attribute_name)
228
- attribute_class = self.class.attrs[attribute_name]
229
- nested_class = self.class.nested_attr_classes[attribute_name]
223
+ return @attributes[attribute_name] if @attributes.has_key? attribute_name
230
224
 
225
+ attribute_class = self.class.attrs[attribute_name]
231
226
  return nil if attribute_class.nil?
232
227
 
233
- attribute = @attributes[attribute_name]
228
+ nested_class = self.class.nested_attr_classes[attribute_name]
234
229
 
235
- unless attribute
236
- @attributes[attribute_name] = attribute_class.new(attribute_name)
237
- attribute = @attributes[attribute_name]
238
- attribute.nested_class = nested_class if nested_class
239
- end
230
+ attribute = attribute_class.new(attribute_name)
231
+ attribute.nested_class = nested_class
240
232
 
241
- attribute
233
+ @attributes[attribute_name] = attribute
242
234
  end
243
235
 
244
236
  def ==(other)
245
237
  return false unless other
246
238
 
247
239
  get_attributes.all? do |attribute|
248
- attribute.value == other.public_send(attribute.name)
240
+ attribute.value == Caller.call(other, attribute.name)
249
241
  end
250
242
  end
251
243
 
@@ -297,9 +289,7 @@ class Bound
297
289
  begin
298
290
  value = attribute.call_on(object)
299
291
  assign_to_receiver attribute, value
300
- rescue BoundClass::Attribute::NotImplemented
301
- # no assignment if object hasn't desired method
302
- # this prevents null-assignments
292
+ rescue NoMethodError
303
293
  end
304
294
  end
305
295
  end
@@ -307,15 +297,8 @@ class Bound
307
297
  private
308
298
  def assign_to_receiver(attribute, value)
309
299
  method = "#{attribute.name}="
310
- send_method @receiver, method, value
300
+ @receiver.send(method, value)
311
301
  end
312
302
 
313
- def send_method(receiver, method, *args)
314
- if receiver.respond_to?(method)
315
- receiver.send method, *args
316
- else
317
- raise NoMethodError, "undefined method `#{method}' for #{receiver}"
318
- end
319
- end
320
303
  end
321
304
  end
@@ -0,0 +1,23 @@
1
+ class Bound
2
+ class PublicSendCaller
3
+ def self.call(object, method, *args)
4
+ object.public_send(method, *args)
5
+ end
6
+ end
7
+
8
+ class ManualCaller
9
+ def self.call(object, method, *args)
10
+ if object.respond_to?(method)
11
+ object.send method, *args
12
+ else
13
+ raise NoMethodError, "undefined method `#{method}' for #{object}"
14
+ end
15
+ end
16
+ end
17
+
18
+ if Object.respond_to? :public_send
19
+ Caller = PublicSendCaller
20
+ else
21
+ Caller = ManualCaller
22
+ end
23
+ end
@@ -1,3 +1,3 @@
1
1
  class Bound
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -351,15 +351,12 @@ describe Bound do
351
351
 
352
352
  it 'overwrites attributes from first to last' do
353
353
  overwriting_hash = {:nose_color => 'RED'}
354
- overwriting_object = HashObject.new(overwriting_hash)
355
354
 
356
355
  [hash, object].each do |subject|
357
- [overwriting_hash, overwriting_object].each do |overwriting_subject|
358
- user = FunnyUser.new(subject, overwriting_subject)
356
+ user = FunnyUser.new(subject, overwriting_hash)
359
357
 
360
- assertion_description = [subject, overwriting_subject].inspect
361
- assert_equal 'RED', user.nose_color, assertion_description
362
- end
358
+ assertion_description = [subject, overwriting_hash].inspect
359
+ assert_equal 'RED', user.nose_color, assertion_description
363
360
  end
364
361
  end
365
362
  end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Bound::Caller do
4
+
5
+ it 'calls the given method with args' do
6
+ assert_equal [22], Bound::Caller.call([], :push, 22)
7
+ end
8
+
9
+ it 'raises if method was not found' do
10
+ assert_raises NoMethodError do
11
+ Bound::Caller.call(22, :foobar)
12
+ end
13
+ end
14
+
15
+ end
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: 1.0.1
4
+ version: 1.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: 2014-04-09 00:00:00.000000000 Z
12
+ date: 2014-05-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -84,8 +84,10 @@ files:
84
84
  - benchmark.rb
85
85
  - bound.gemspec
86
86
  - lib/bound.rb
87
+ - lib/bound/caller.rb
87
88
  - lib/bound/version.rb
88
89
  - spec/bound_spec.rb
90
+ - spec/caller_spec.rb
89
91
  - spec/hash_object_spec.rb
90
92
  - spec/spec_helper.rb
91
93
  - spec/support/hash_object.rb
@@ -115,6 +117,7 @@ specification_version: 4
115
117
  summary: Implements a nice helper for fast boundary definitions
116
118
  test_files:
117
119
  - spec/bound_spec.rb
120
+ - spec/caller_spec.rb
118
121
  - spec/hash_object_spec.rb
119
122
  - spec/spec_helper.rb
120
123
  - spec/support/hash_object.rb