bound 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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