attr_extras 4.3.0 → 4.4.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/.travis.yml +3 -2
- data/README.md +25 -0
- data/Rakefile +16 -2
- data/lib/attr_extras.rb +2 -94
- data/lib/attr_extras/explicit.rb +99 -0
- data/lib/attr_extras/version.rb +1 -1
- data/spec/{attr_id_query_spec.rb → attr_extras/attr_id_query_spec.rb} +1 -1
- data/spec/{attr_implement_spec.rb → attr_extras/attr_implement_spec.rb} +1 -1
- data/spec/{attr_initialize_spec.rb → attr_extras/attr_initialize_spec.rb} +1 -1
- data/spec/{attr_private_spec.rb → attr_extras/attr_private_spec.rb} +1 -1
- data/spec/{attr_query_spec.rb → attr_extras/attr_query_spec.rb} +1 -1
- data/spec/{attr_value_spec.rb → attr_extras/attr_value_spec.rb} +1 -1
- data/spec/attr_extras/explicit_spec.rb +23 -0
- data/spec/{method_object_spec.rb → attr_extras/method_object_spec.rb} +1 -1
- data/spec/{pattr_initialize_spec.rb → attr_extras/pattr_initialize_spec.rb} +1 -1
- data/spec/{rattr_initialize_spec.rb → attr_extras/rattr_initialize_spec.rb} +1 -1
- data/spec/{static_facade_spec.rb → attr_extras/static_facade_spec.rb} +1 -1
- data/spec/{vattr_initialize_spec.rb → attr_extras/vattr_initialize_spec.rb} +1 -1
- data/spec/attr_extras_spec.rb +3 -3
- data/spec/spec_helper.rb +1 -4
- data/spec/spec_helper_without_loading_attr_extras.rb +4 -0
- metadata +30 -26
- data/.rvmrc +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9a302397db869ccd71c2f96bed2c343468d4c1fb
|
4
|
+
data.tar.gz: 4753ba73b9809a4f4d24943058329bb491a796ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc2e5f3b692f3881884296fea5495bfd7da4986ff992552d4bb84eafd789495b2985c3dbac6f0f4bb0d232fdcd1333ad8540bb8c6d474a633aa110d8c13b65bc
|
7
|
+
data.tar.gz: 641b94a27502ff6263a13f5451970a92d5202897c4a3b8b2430e812db9e5403865396f3f6d51d2cf1729fce791e8693bf12371e9a90beb5b0e8e507eafaba74a
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -286,6 +286,29 @@ though it is shorter, more declarative, gives you a clear message and handles ed
|
|
286
286
|
`attr_id_query :foo?, :bar?` defines query methods like `foo?`, which is true if (and only if) `foo_id` is truthy. Goes well with Active Record.
|
287
287
|
|
288
288
|
|
289
|
+
## Explicit mode
|
290
|
+
|
291
|
+
By default, attr\_extras will add methods to every class and module.
|
292
|
+
|
293
|
+
This is not ideal if you're using attr\_extras in a library: those who depend on your library will get those methods as well.
|
294
|
+
|
295
|
+
It's also not obvious where the methods come from. You can be more explicit about it, and restrict where the methods are added, like this:
|
296
|
+
|
297
|
+
```
|
298
|
+
require "attr_extras/explicit"
|
299
|
+
|
300
|
+
class MyLib
|
301
|
+
extend AttrExtras.mixin
|
302
|
+
|
303
|
+
pattr_initialize :now_this_class_can_use_attr_extras
|
304
|
+
end
|
305
|
+
```
|
306
|
+
|
307
|
+
Crucially, you need to `require "attr_extras/explicit"` *instead of* `require "attr_extras"`. Some frameworks, like Ruby on Rails, may automatically require everything in your `Gemfile`. You can avoid that with `gem "attr_extras", require: "attr_extras/explicit"`.
|
308
|
+
|
309
|
+
In explicit mode, you need to call `extend AttrExtras.mixin` *in every class* that wants the attr\_extras methods.
|
310
|
+
|
311
|
+
|
289
312
|
## Philosophy
|
290
313
|
|
291
314
|
Findability is a core value.
|
@@ -333,6 +356,8 @@ Or to see warnings (try not to have any):
|
|
333
356
|
|
334
357
|
`RUBYOPT=-w rake`
|
335
358
|
|
359
|
+
The tests are intentionally split into two test suites for reasons described in `Rakefile`.
|
360
|
+
|
336
361
|
|
337
362
|
## Contributors
|
338
363
|
|
data/Rakefile
CHANGED
@@ -2,8 +2,22 @@
|
|
2
2
|
require "bundler/gem_tasks"
|
3
3
|
require "rake/testtask"
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
# "Explicit mode" cannot be truly tested if that process has already `require`d attr_extras.
|
6
|
+
# Thus, we need separate test suites.
|
7
|
+
|
8
|
+
explicit_tests = [ "spec/attr_extras/explicit_spec.rb" ]
|
9
|
+
|
10
|
+
Rake::TestTask.new(:test_implicit) do |t|
|
11
|
+
implicit_tests = FileList["spec/**/*_spec.rb"] - explicit_tests
|
12
|
+
|
13
|
+
t.libs << "spec"
|
14
|
+
t.test_files = implicit_tests
|
15
|
+
end
|
16
|
+
|
17
|
+
Rake::TestTask.new(:test_explicit) do |t|
|
18
|
+
t.libs << "spec"
|
19
|
+
t.test_files = explicit_tests
|
7
20
|
end
|
8
21
|
|
22
|
+
task :test => [ :test_implicit, :test_explicit ]
|
9
23
|
task :default => :test
|
data/lib/attr_extras.rb
CHANGED
@@ -1,97 +1,5 @@
|
|
1
|
-
require "attr_extras/
|
2
|
-
require "attr_extras/attr_initialize"
|
3
|
-
require "attr_extras/attr_value"
|
4
|
-
require "attr_extras/attr_query"
|
5
|
-
require "attr_extras/utils"
|
6
|
-
|
7
|
-
module AttrExtras
|
8
|
-
# To avoid masking coding errors, we don't inherit from StandardError (which would be implicitly rescued). Forgetting to define a requisite method isn't just some runtime error.
|
9
|
-
class MethodNotImplementedError < Exception; end
|
10
|
-
|
11
|
-
module ModuleMethods
|
12
|
-
def attr_initialize(*names, &block)
|
13
|
-
AttrInitialize.new(self, names, block).apply
|
14
|
-
end
|
15
|
-
|
16
|
-
def attr_private(*names)
|
17
|
-
# Need this to avoid "private attribute?" warnings when running
|
18
|
-
# the full test suite; not sure why exactly.
|
19
|
-
public
|
20
|
-
|
21
|
-
attr_reader(*names)
|
22
|
-
private(*names)
|
23
|
-
end
|
24
|
-
|
25
|
-
def attr_value(*names)
|
26
|
-
AttrValue.new(self, *names).apply
|
27
|
-
end
|
28
|
-
|
29
|
-
def pattr_initialize(*names, &block)
|
30
|
-
attr_initialize(*names, &block)
|
31
|
-
attr_private(*Utils.flat_names(names))
|
32
|
-
end
|
33
|
-
|
34
|
-
alias_method :attr_private_initialize, :pattr_initialize
|
35
|
-
|
36
|
-
def vattr_initialize(*names, &block)
|
37
|
-
attr_initialize(*names, &block)
|
38
|
-
attr_value(*Utils.flat_names(names))
|
39
|
-
end
|
40
|
-
|
41
|
-
alias_method :attr_value_initialize, :vattr_initialize
|
42
|
-
|
43
|
-
def rattr_initialize(*names, &block)
|
44
|
-
attr_initialize(*names, &block)
|
45
|
-
attr_reader(*Utils.flat_names(names))
|
46
|
-
end
|
47
|
-
|
48
|
-
alias_method :attr_reader_initialize, :rattr_initialize
|
49
|
-
|
50
|
-
def static_facade(method_name, *names)
|
51
|
-
define_singleton_method(method_name) do |*values|
|
52
|
-
new(*values).public_send(method_name)
|
53
|
-
end
|
54
|
-
|
55
|
-
pattr_initialize(*names)
|
56
|
-
end
|
57
|
-
|
58
|
-
def method_object(*names)
|
59
|
-
static_facade :call, *names
|
60
|
-
end
|
61
|
-
|
62
|
-
def attr_query(*names)
|
63
|
-
AttrQuery.define_with_suffix(self, "", *names)
|
64
|
-
end
|
65
|
-
|
66
|
-
def attr_id_query(*names)
|
67
|
-
AttrQuery.define_with_suffix(self, "_id", *names)
|
68
|
-
end
|
69
|
-
|
70
|
-
def attr_implement(*names)
|
71
|
-
arg_names = names.last.is_a?(Array) ? names.pop : []
|
72
|
-
arity = arg_names.length
|
73
|
-
|
74
|
-
mod = Module.new do
|
75
|
-
define_method :method_missing do |name, *args|
|
76
|
-
if names.include?(name)
|
77
|
-
provided_arity = args.length
|
78
|
-
|
79
|
-
if provided_arity != arity
|
80
|
-
raise ArgumentError, "wrong number of arguments (#{provided_arity} for #{arity})"
|
81
|
-
end
|
82
|
-
|
83
|
-
raise MethodNotImplementedError, "Implement a '#{name}(#{arg_names.join(", ")})' method"
|
84
|
-
else
|
85
|
-
super(name, *args)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
include mod
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
1
|
+
require "attr_extras/explicit"
|
94
2
|
|
95
3
|
class Module
|
96
|
-
include AttrExtras
|
4
|
+
include AttrExtras.mixin
|
97
5
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require "attr_extras/version"
|
2
|
+
require "attr_extras/attr_initialize"
|
3
|
+
require "attr_extras/attr_value"
|
4
|
+
require "attr_extras/attr_query"
|
5
|
+
require "attr_extras/utils"
|
6
|
+
|
7
|
+
module AttrExtras
|
8
|
+
# To avoid masking coding errors, we don't inherit from StandardError (which would be implicitly rescued). Forgetting to define a requisite method isn't just some runtime error.
|
9
|
+
class MethodNotImplementedError < Exception; end
|
10
|
+
|
11
|
+
def self.mixin
|
12
|
+
self::ModuleMethods
|
13
|
+
end
|
14
|
+
|
15
|
+
# Separate module for `include`ing so that mixing in the methods doesn't also mix in constants:
|
16
|
+
# http://thepugautomatic.com/2014/02/private-api/
|
17
|
+
module ModuleMethods
|
18
|
+
def attr_initialize(*names, &block)
|
19
|
+
AttrInitialize.new(self, names, block).apply
|
20
|
+
end
|
21
|
+
|
22
|
+
def attr_private(*names)
|
23
|
+
# Need this to avoid "private attribute?" warnings when running
|
24
|
+
# the full test suite; not sure why exactly.
|
25
|
+
public
|
26
|
+
|
27
|
+
attr_reader(*names)
|
28
|
+
private(*names)
|
29
|
+
end
|
30
|
+
|
31
|
+
def attr_value(*names)
|
32
|
+
AttrValue.new(self, *names).apply
|
33
|
+
end
|
34
|
+
|
35
|
+
def pattr_initialize(*names, &block)
|
36
|
+
attr_initialize(*names, &block)
|
37
|
+
attr_private(*Utils.flat_names(names))
|
38
|
+
end
|
39
|
+
|
40
|
+
alias_method :attr_private_initialize, :pattr_initialize
|
41
|
+
|
42
|
+
def vattr_initialize(*names, &block)
|
43
|
+
attr_initialize(*names, &block)
|
44
|
+
attr_value(*Utils.flat_names(names))
|
45
|
+
end
|
46
|
+
|
47
|
+
alias_method :attr_value_initialize, :vattr_initialize
|
48
|
+
|
49
|
+
def rattr_initialize(*names, &block)
|
50
|
+
attr_initialize(*names, &block)
|
51
|
+
attr_reader(*Utils.flat_names(names))
|
52
|
+
end
|
53
|
+
|
54
|
+
alias_method :attr_reader_initialize, :rattr_initialize
|
55
|
+
|
56
|
+
def static_facade(method_name, *names)
|
57
|
+
define_singleton_method(method_name) do |*values|
|
58
|
+
new(*values).public_send(method_name)
|
59
|
+
end
|
60
|
+
|
61
|
+
pattr_initialize(*names)
|
62
|
+
end
|
63
|
+
|
64
|
+
def method_object(*names)
|
65
|
+
static_facade :call, *names
|
66
|
+
end
|
67
|
+
|
68
|
+
def attr_query(*names)
|
69
|
+
AttrQuery.define_with_suffix(self, "", *names)
|
70
|
+
end
|
71
|
+
|
72
|
+
def attr_id_query(*names)
|
73
|
+
AttrQuery.define_with_suffix(self, "_id", *names)
|
74
|
+
end
|
75
|
+
|
76
|
+
def attr_implement(*names)
|
77
|
+
arg_names = names.last.is_a?(Array) ? names.pop : []
|
78
|
+
arity = arg_names.length
|
79
|
+
|
80
|
+
mod = Module.new do
|
81
|
+
define_method :method_missing do |name, *args|
|
82
|
+
if names.include?(name)
|
83
|
+
provided_arity = args.length
|
84
|
+
|
85
|
+
if provided_arity != arity
|
86
|
+
raise ArgumentError, "wrong number of arguments (#{provided_arity} for #{arity})"
|
87
|
+
end
|
88
|
+
|
89
|
+
raise MethodNotImplementedError, "Implement a '#{name}(#{arg_names.join(", ")})' method"
|
90
|
+
else
|
91
|
+
super(name, *args)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
include mod
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/attr_extras/version.rb
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
require "spec_helper_without_loading_attr_extras"
|
2
|
+
require "attr_extras/explicit"
|
3
|
+
|
4
|
+
# Sanity check.
|
5
|
+
if String.respond_to?(:pattr_initialize)
|
6
|
+
raise "Expected this test suite not to have AttrExtras mixed in!"
|
7
|
+
end
|
8
|
+
|
9
|
+
describe AttrExtras, "explicit mode" do
|
10
|
+
it "must have methods mixed in explicitly" do
|
11
|
+
has_methods_before_mixin = nil
|
12
|
+
has_methods_after_mixin = nil
|
13
|
+
|
14
|
+
Class.new do
|
15
|
+
has_methods_before_mixin = respond_to?(:pattr_initialize)
|
16
|
+
extend AttrExtras.mixin
|
17
|
+
has_methods_after_mixin = respond_to?(:pattr_initialize)
|
18
|
+
end
|
19
|
+
|
20
|
+
refute has_methods_before_mixin
|
21
|
+
assert has_methods_after_mixin
|
22
|
+
end
|
23
|
+
end
|
data/spec/attr_extras_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
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: 4.
|
4
|
+
version: 4.4.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-
|
13
|
+
date: 2015-03-08 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: minitest
|
@@ -48,7 +48,6 @@ extensions: []
|
|
48
48
|
extra_rdoc_files: []
|
49
49
|
files:
|
50
50
|
- ".gitignore"
|
51
|
-
- ".rvmrc"
|
52
51
|
- ".travis.yml"
|
53
52
|
- Gemfile
|
54
53
|
- LICENSE.txt
|
@@ -59,22 +58,25 @@ files:
|
|
59
58
|
- lib/attr_extras/attr_initialize.rb
|
60
59
|
- lib/attr_extras/attr_query.rb
|
61
60
|
- lib/attr_extras/attr_value.rb
|
61
|
+
- lib/attr_extras/explicit.rb
|
62
62
|
- lib/attr_extras/utils.rb
|
63
63
|
- lib/attr_extras/version.rb
|
64
64
|
- script/test
|
65
|
+
- spec/attr_extras/attr_id_query_spec.rb
|
66
|
+
- spec/attr_extras/attr_implement_spec.rb
|
67
|
+
- spec/attr_extras/attr_initialize_spec.rb
|
68
|
+
- spec/attr_extras/attr_private_spec.rb
|
69
|
+
- spec/attr_extras/attr_query_spec.rb
|
70
|
+
- spec/attr_extras/attr_value_spec.rb
|
71
|
+
- spec/attr_extras/explicit_spec.rb
|
72
|
+
- spec/attr_extras/method_object_spec.rb
|
73
|
+
- spec/attr_extras/pattr_initialize_spec.rb
|
74
|
+
- spec/attr_extras/rattr_initialize_spec.rb
|
75
|
+
- spec/attr_extras/static_facade_spec.rb
|
76
|
+
- spec/attr_extras/vattr_initialize_spec.rb
|
65
77
|
- spec/attr_extras_spec.rb
|
66
|
-
- spec/attr_id_query_spec.rb
|
67
|
-
- spec/attr_implement_spec.rb
|
68
|
-
- spec/attr_initialize_spec.rb
|
69
|
-
- spec/attr_private_spec.rb
|
70
|
-
- spec/attr_query_spec.rb
|
71
|
-
- spec/attr_value_spec.rb
|
72
|
-
- spec/method_object_spec.rb
|
73
|
-
- spec/pattr_initialize_spec.rb
|
74
|
-
- spec/rattr_initialize_spec.rb
|
75
78
|
- spec/spec_helper.rb
|
76
|
-
- spec/
|
77
|
-
- spec/vattr_initialize_spec.rb
|
79
|
+
- spec/spec_helper_without_loading_attr_extras.rb
|
78
80
|
homepage: https://github.com/barsoom/attr_extras
|
79
81
|
licenses:
|
80
82
|
- MIT
|
@@ -95,21 +97,23 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
97
|
version: '0'
|
96
98
|
requirements: []
|
97
99
|
rubyforge_project:
|
98
|
-
rubygems_version: 2.
|
100
|
+
rubygems_version: 2.2.2
|
99
101
|
signing_key:
|
100
102
|
specification_version: 4
|
101
103
|
summary: Takes some boilerplate out of Ruby with methods like attr_initialize.
|
102
104
|
test_files:
|
105
|
+
- spec/attr_extras/attr_id_query_spec.rb
|
106
|
+
- spec/attr_extras/attr_implement_spec.rb
|
107
|
+
- spec/attr_extras/attr_initialize_spec.rb
|
108
|
+
- spec/attr_extras/attr_private_spec.rb
|
109
|
+
- spec/attr_extras/attr_query_spec.rb
|
110
|
+
- spec/attr_extras/attr_value_spec.rb
|
111
|
+
- spec/attr_extras/explicit_spec.rb
|
112
|
+
- spec/attr_extras/method_object_spec.rb
|
113
|
+
- spec/attr_extras/pattr_initialize_spec.rb
|
114
|
+
- spec/attr_extras/rattr_initialize_spec.rb
|
115
|
+
- spec/attr_extras/static_facade_spec.rb
|
116
|
+
- spec/attr_extras/vattr_initialize_spec.rb
|
103
117
|
- spec/attr_extras_spec.rb
|
104
|
-
- spec/attr_id_query_spec.rb
|
105
|
-
- spec/attr_implement_spec.rb
|
106
|
-
- spec/attr_initialize_spec.rb
|
107
|
-
- spec/attr_private_spec.rb
|
108
|
-
- spec/attr_query_spec.rb
|
109
|
-
- spec/attr_value_spec.rb
|
110
|
-
- spec/method_object_spec.rb
|
111
|
-
- spec/pattr_initialize_spec.rb
|
112
|
-
- spec/rattr_initialize_spec.rb
|
113
118
|
- spec/spec_helper.rb
|
114
|
-
- spec/
|
115
|
-
- spec/vattr_initialize_spec.rb
|
119
|
+
- spec/spec_helper_without_loading_attr_extras.rb
|
data/.rvmrc
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
rvm ruby-1.9.3-p0-patched@attr_extras --create
|