attr_extras 3.2.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZWFjODUyMWM5ZDQwYTllYzlkYWU4YjkwNzBkOWQ1YjY0NTE5MWY0ZQ==
4
+ YTEzMGU2ZTk5YTFhZTRkOGRjN2NjMDNkYTU4MDM4NTVkNDExNmVkOQ==
5
5
  data.tar.gz: !binary |-
6
- NzI4N2YyZjcwN2ZkZDIzMmIyN2I2NmI3NDJjMGNlZTQyNjZkOGNmYw==
6
+ MDZkNDRkNzc2MDMyOGUwMzVjODE1YmE5NGNkODNhMjY4YTM5NzZjYw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NTUxMDVlN2I2NzI4NzY4MjBkMGM4OWQ0OGM5M2NjNGRkYzdiNzRiOWNiYzQ5
10
- YTEyZTFhMjkxNjg3YTU2ZWJkMTgxNjU0OTU5NjcxNzY2YjYzODA0NTNlZmY4
11
- MzYxZTc2ZTE5YzdiMjg1OTEzMmE1ODNmYzJjYmQ5OTkxMzZiODI=
9
+ MWNjNjMyYjQ3ZTMyMDE5MTQwYWIyY2NjYzQxMjJkNTNjNTQxOGZhMzY2NjAw
10
+ MmZkM2U3NzNiOTBjMWVmYzQyODA4MzBhMWU3ODIyYmZkNjFjODRhYTAzOTlm
11
+ MGY0NjEzYWIxZjU5MDhlNjRmNDkzYmZlMWVjMmY0ODQ5MWY0YWI=
12
12
  data.tar.gz: !binary |-
13
- YmRlYTAwYWQzMmJiODA2ZTk5YzEyMDVkNGVmY2JiODI5MGUxYTAxNWQzNDIx
14
- MjAyZWM3OTUwOWMzN2Y0NDkxZjhkOGYwYmM0ZmNjM2JhMTg0MDQ1ZGM3NGQw
15
- ZmE2YzM1MGE2ODU2YTExZGZmNGM5NmZhYzI3YzgwMTFjODNjMzQ=
13
+ MWNiMmYwMDI5MDYzZjBjYWY2OGFhNTMyZWIyZjJjZDkzNDRlOWUxY2Q3NzNm
14
+ ZWJhYWViN2I5NmU1ZWY1OWFhODQ3NGEwOTY1YmE3MGZjNWY5YTU0NTY5YWU2
15
+ ODgwNjZmOGE2MjQzZmQ0MzE5ZDY5OTYyMzhjNjVlODk2NzMyMGQ=
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012-2014 Barsoom AB (http://barsoom.se)
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -83,18 +83,57 @@ attr_value :foo, :bar
83
83
  The `attr_initialize` notation for hash arguments is also supported: `vattr_initialize :foo, [:bar, :baz!]`
84
84
 
85
85
 
86
- ### `method_object :fooable?, :foo`<br>
86
+ ### `static_facade :fooable?, :foo`<br>
87
87
 
88
- Defines a `.fooable?` class method that takes arguments (`foo`) and delegates to an instance method that can access those arguments as private readers.
88
+ Defines a `.fooable?` class method that delegates to an instance method by the same name, having first provided `foo` as a private reader.
89
89
 
90
- This is useful for [method objects](http://refactoring.com/catalog/replaceMethodWithMethodObject.html):
90
+ This is handy when a class-method API makes sense but you still want [the refactorability of instance methods](http://blog.codeclimate.com/blog/2012/11/14/why-ruby-class-methods-resist-refactoring/).
91
+
92
+ ``` ruby
93
+ class PublishingPolicy
94
+ static_facade :allow?, :user
95
+ static_facade :disallow?, :user
96
+
97
+ def allow?
98
+ user.admin? && …
99
+ end
100
+
101
+ def disallow?
102
+ !allow?
103
+ end
104
+ end
105
+
106
+ PublishingPolicy.allow?(user)
107
+ ```
108
+
109
+ `static_facade :fooable?, :foo` is a shortcut for
110
+
111
+ ``` ruby
112
+ pattr_initialize :foo
113
+
114
+ def self.fooable?(foo)
115
+ new(foo).fooable?
116
+ end
117
+ ```
118
+
119
+ The `attr_initialize` notation for hash arguments is also supported: `static_facade :fooable?, :foo, [:bar, :baz!]`
120
+
121
+ You don't have to specify arguments/readers if you don't want them: just `static_facade :fooable?` is also valid.
122
+
123
+
124
+ ### `method_object :foo`
125
+
126
+ *NOTE: v4.0.0 made a breaking change! `static_facade` does exactly what `method_object` used to do; the new `method_object` no longer accepts a method name argument.*
127
+
128
+ Defines a `.call` class method that delegates to an instance method by the same name, having first provided `foo` as a private reader.
129
+
130
+ This is a special case of `static_facade` for when you want a [Method Object](http://refactoring.com/catalog/replaceMethodWithMethodObject.html), and the class name itself will communicate the action it performs.
91
131
 
92
132
  ``` ruby
93
133
  class PriceCalculator
94
- method_object :calculate,
95
- :order
134
+ method_object :order
96
135
 
97
- def calculate
136
+ def call
98
137
  total * factor
99
138
  end
100
139
 
@@ -111,27 +150,30 @@ end
111
150
 
112
151
  class Order
113
152
  def price
114
- PriceCalculator.calculate(self)
153
+ PriceCalculator.call(self)
115
154
  end
116
-
117
- # …
118
155
  end
119
156
  ```
120
157
 
121
- Shortcut for
158
+ `method_object :foo` is a shortcut for
159
+
160
+ ``` ruby
161
+ static_facade :call, :foo
162
+ ```
163
+
164
+ which is a shortcut for
122
165
 
123
166
  ``` ruby
124
- attr_initialize :foo
125
- attr_private :foo
167
+ pattr_initialize :foo
126
168
 
127
- def self.fooable?(foo)
128
- new(foo).fooable?
169
+ def self.call(foo)
170
+ new(foo).call
129
171
  end
130
172
  ```
131
173
 
132
- The `attr_initialize` notation for hash arguments is also supported: `method_object :fooable?, :foo, [:bar, :baz!]`
174
+ The `attr_initialize` notation for hash arguments is also supported: `method_object :foo, [:bar, :baz!]`
133
175
 
134
- You don't have to specify readers if you don't want them: `method_object :fooable?` is also valid.
176
+ You don't have to specify arguments/readers if you don't want them: just `method_object` is also valid.
135
177
 
136
178
 
137
179
  ### `attr_id_query :foo?, :bar?`<br>
@@ -151,6 +193,16 @@ Defines nullary (0-argument) methods `foo` and `bar` that raise e.g. `"Implement
151
193
 
152
194
  This is suitable for [abstract methods](http://en.wikipedia.org/wiki/Abstract_method#Abstract_methods) in base classes, e.g. when using the [template method pattern](http://en.wikipedia.org/wiki/Template_method_pattern).
153
195
 
196
+ It's more or less a shortcut for
197
+
198
+ ``` ruby
199
+ def my_method
200
+ raise "Implement me in a subclass!"
201
+ end
202
+ ```
203
+
204
+ though it is shorter, more declarative, gives you a clear message and handles edge cases you might not have thought about (see tests).
205
+
154
206
 
155
207
  ## Philosophy
156
208
 
@@ -211,25 +263,4 @@ Or to see warnings (try not to have any):
211
263
 
212
264
  ## License
213
265
 
214
- Copyright (c) 2012-2014 [Barsoom AB](http://barsoom.se)
215
-
216
- MIT License
217
-
218
- Permission is hereby granted, free of charge, to any person obtaining
219
- a copy of this software and associated documentation files (the
220
- "Software"), to deal in the Software without restriction, including
221
- without limitation the rights to use, copy, modify, merge, publish,
222
- distribute, sublicense, and/or sell copies of the Software, and to
223
- permit persons to whom the Software is furnished to do so, subject to
224
- the following conditions:
225
-
226
- The above copyright notice and this permission notice shall be
227
- included in all copies or substantial portions of the Software.
228
-
229
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
230
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
231
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
232
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
233
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
234
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
235
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
266
+ [MIT](LICENSE.txt)
@@ -46,7 +46,7 @@ module AttrExtras
46
46
  attr_value(*Utils.flat_names(names))
47
47
  end
48
48
 
49
- def method_object(method_name, *names)
49
+ def static_facade(method_name, *names)
50
50
  define_singleton_method(method_name) do |*values|
51
51
  new(*values).public_send(method_name)
52
52
  end
@@ -54,6 +54,10 @@ module AttrExtras
54
54
  pattr_initialize(*names)
55
55
  end
56
56
 
57
+ def method_object(*names)
58
+ static_facade :call, *names
59
+ end
60
+
57
61
  def attr_query(*names)
58
62
  AttrQuery.define_with_suffix(self, "", *names)
59
63
  end
@@ -1,3 +1,3 @@
1
1
  module AttrExtras
2
- VERSION = "3.2.0"
2
+ VERSION = "4.0.0"
3
3
  end
@@ -38,9 +38,13 @@ describe Object, ".attr_implement" do
38
38
  subklass.new.foo.must_equal "bar"
39
39
  end
40
40
 
41
- # E.g. Active Record defines column query methods like "admin?"
41
+ # E.g. when Active Record defines column query methods like "admin?"
42
42
  # higher up in the ancestor chain.
43
43
  it "does not raise if method is implemented in a superclass" do
44
+ foo_interface = Module.new do
45
+ attr_implement :foo
46
+ end
47
+
44
48
  superklass = Class.new do
45
49
  def foo
46
50
  "bar"
@@ -48,9 +52,17 @@ describe Object, ".attr_implement" do
48
52
  end
49
53
 
50
54
  klass = Class.new(superklass) do
51
- attr_implement :foo
55
+ include foo_interface
52
56
  end
53
57
 
54
58
  klass.new.foo.must_equal "bar"
55
59
  end
60
+
61
+ it "does not mess up missing-method handling" do
62
+ klass = Class.new do
63
+ attr_implement :foo
64
+ end
65
+
66
+ lambda { klass.new.some_other_method }.must_raise NoMethodError
67
+ end
56
68
  end
@@ -1,29 +1,28 @@
1
1
  require_relative "spec_helper"
2
2
 
3
3
  describe Object, ".method_object" do
4
- it "creates a class method that instantiates and runs that instance method" do
4
+ it "creates a .call class method that instantiates and runs the #call instance method" do
5
5
  klass = Class.new do
6
- method_object :fooable?,
7
- :foo
6
+ method_object :foo
8
7
 
9
- def fooable?
8
+ def call
10
9
  foo
11
10
  end
12
11
  end
13
12
 
14
- assert klass.fooable?(true)
15
- refute klass.fooable?(false)
13
+ assert klass.call(true)
14
+ refute klass.call(false)
16
15
  end
17
16
 
18
17
  it "doesn't require attributes" do
19
18
  klass = Class.new do
20
- method_object :fooable?
19
+ method_object
21
20
 
22
- def fooable?
21
+ def call
23
22
  true
24
23
  end
25
24
  end
26
25
 
27
- assert klass.fooable?
26
+ assert klass.call
28
27
  end
29
28
  end
@@ -0,0 +1,29 @@
1
+ require_relative "spec_helper"
2
+
3
+ describe Object, ".static_facade" do
4
+ it "creates a class method that instantiates and runs that instance method" do
5
+ klass = Class.new do
6
+ static_facade :fooable?,
7
+ :foo
8
+
9
+ def fooable?
10
+ foo
11
+ end
12
+ end
13
+
14
+ assert klass.fooable?(true)
15
+ refute klass.fooable?(false)
16
+ end
17
+
18
+ it "doesn't require attributes" do
19
+ klass = Class.new do
20
+ static_facade :fooable?
21
+
22
+ def fooable?
23
+ true
24
+ end
25
+ end
26
+
27
+ assert klass.fooable?
28
+ end
29
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attr_extras
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henrik Nyh
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-01-10 00:00:00.000000000 Z
13
+ date: 2015-01-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
@@ -37,6 +37,7 @@ files:
37
37
  - .rvmrc
38
38
  - .travis.yml
39
39
  - Gemfile
40
+ - LICENSE.txt
40
41
  - README.md
41
42
  - Rakefile
42
43
  - attr_extras.gemspec
@@ -56,6 +57,7 @@ files:
56
57
  - spec/method_object_spec.rb
57
58
  - spec/pattr_initialize_spec.rb
58
59
  - spec/spec_helper.rb
60
+ - spec/static_facade_spec.rb
59
61
  - spec/vattr_initialize_spec.rb
60
62
  homepage: https://github.com/barsoom/attr_extras
61
63
  licenses:
@@ -92,4 +94,5 @@ test_files:
92
94
  - spec/method_object_spec.rb
93
95
  - spec/pattr_initialize_spec.rb
94
96
  - spec/spec_helper.rb
97
+ - spec/static_facade_spec.rb
95
98
  - spec/vattr_initialize_spec.rb