usable 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +27 -41
- data/bin/console +0 -15
- data/lib/usable/mod_extender.rb +14 -27
- data/lib/usable/version.rb +1 -1
- data/lib/usable.rb +5 -12
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a14205274f753668d3b6bc7002739321e22f445f
|
4
|
+
data.tar.gz: a21a914e5cf9850a7c4bb88708f187a017e0bad7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f784949ee494ce858e395e5066cbcb48e9dcd153975d71eac80ed3fb1bda5f473547cc43e41ebbfded0567ebb5ab69543b9f935714ff371d7a5e52a25562f65
|
7
|
+
data.tar.gz: 2231963745230a5a9eae47652db32a6b5ba874c887aab232f3fee3e0e73b41b216803baef6943a888a241d450997336fa62dd24597086bf2e380ac6e7e723764
|
data/README.md
CHANGED
@@ -27,7 +27,7 @@ class Model
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def save
|
30
|
-
|
30
|
+
save_version
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -46,11 +46,35 @@ Usable reserves the `:only` and `:method` keys. All other keys in the given hash
|
|
46
46
|
want to define a config on the target class with one of these names, you can simply define them in the block:
|
47
47
|
|
48
48
|
```ruby
|
49
|
-
Model.usable VersionMixin, only: [:save_version] do
|
50
|
-
|
49
|
+
Model.usable VersionMixin, only: [:save_version] do
|
50
|
+
only "Will be set on `Model.usables.only` and namespaced under `Model.usables.version_mixin.only`"
|
51
51
|
end
|
52
52
|
```
|
53
53
|
|
54
|
+
## Configuring Modules
|
55
|
+
|
56
|
+
Configuration settings defined on a "usable" module will be copied to the including class. Usable defines
|
57
|
+
a `config` method on extended modules (alias for `usables`) to use for setting default configuration options:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
module Mixin
|
61
|
+
extend Usable
|
62
|
+
config.language = :en
|
63
|
+
config do
|
64
|
+
country 'US'
|
65
|
+
state 'Hawaii'
|
66
|
+
spec :census, {
|
67
|
+
population: 1_400_00,
|
68
|
+
daily_visitors: 218_150
|
69
|
+
}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
Model.usable Mixin
|
74
|
+
Model.usables[:state] # => 'Hawaii'
|
75
|
+
Model.usables.census[:daily_visitors] # => 218150
|
76
|
+
```
|
77
|
+
|
54
78
|
## Confidently calling methods
|
55
79
|
|
56
80
|
We should all be writing [confident code](http://www.confidentruby.com/), which is why you might want to call configurable
|
@@ -71,44 +95,6 @@ Modules with the following names found within the target module's namespace will
|
|
71
95
|
|
72
96
|
`ClassMethods` - extended onto the target module.
|
73
97
|
|
74
|
-
`UsableSpec` - tells usable which methods are configurable via the `:only` option. Any naming conflicts will be resolved by
|
75
|
-
giving precedence to the parent module.
|
76
|
-
|
77
|
-
For example:
|
78
|
-
|
79
|
-
```ruby
|
80
|
-
module Mixin
|
81
|
-
def name
|
82
|
-
"defined by Mixin"
|
83
|
-
end
|
84
|
-
|
85
|
-
def from_mixin
|
86
|
-
"always here"
|
87
|
-
end
|
88
|
-
|
89
|
-
# @description Usable will apply the :only option to just the methods defined by this module
|
90
|
-
module UsableSpec
|
91
|
-
def from_spec
|
92
|
-
"can be excluded"
|
93
|
-
end
|
94
|
-
|
95
|
-
def name
|
96
|
-
"defined by UsableSpec"
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
class Example
|
102
|
-
extend Usable
|
103
|
-
usable Mixin, only: :from_spec
|
104
|
-
end
|
105
|
-
|
106
|
-
Example.new.from_spec # => "can be excluded"
|
107
|
-
Example.new.from_mixin # => "always here"
|
108
|
-
Example.new.name # => "defined by Mixin"
|
109
|
-
Example.ancestors # => [Example, Mixin, Example::MixinUsableSpecUsed, Object, Kernel, BasicObject] (ruby -v 2.3.0)
|
110
|
-
```
|
111
|
-
|
112
98
|
## Notes
|
113
99
|
|
114
100
|
If the given module is modified by the `:only` option, then Usable will duplicate the module so that it doesn't mutate
|
data/bin/console
CHANGED
@@ -27,21 +27,6 @@ module Mixin
|
|
27
27
|
def name
|
28
28
|
"defined by Mixin"
|
29
29
|
end
|
30
|
-
|
31
|
-
def from_mixin
|
32
|
-
"always here"
|
33
|
-
end
|
34
|
-
|
35
|
-
# @description Usable will apply the :only to just the methods defined by this module
|
36
|
-
module UsableSpec
|
37
|
-
def from_spec
|
38
|
-
"can be excluded"
|
39
|
-
end
|
40
|
-
|
41
|
-
def name
|
42
|
-
"defined by UsableSpec"
|
43
|
-
end
|
44
|
-
end
|
45
30
|
end
|
46
31
|
|
47
32
|
class Model
|
data/lib/usable/mod_extender.rb
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
module Usable
|
2
2
|
class ModExtender
|
3
|
-
SPEC = :UsableSpec
|
4
|
-
CLASS_MODULE = :ClassMethods
|
5
|
-
|
6
3
|
attr_reader :name
|
7
4
|
attr_accessor :copy, :mod, :options, :unwanted
|
8
5
|
|
@@ -10,29 +7,17 @@ module Usable
|
|
10
7
|
@mod = mod
|
11
8
|
@options = options
|
12
9
|
@options[:method] ||= :include
|
13
|
-
|
14
|
-
|
15
|
-
@name = "#{mod.name}UsableSpec"
|
16
|
-
else
|
17
|
-
@copy = mod
|
18
|
-
@name = mod.name
|
19
|
-
end
|
10
|
+
@copy = mod
|
11
|
+
@name = mod.name
|
20
12
|
@unwanted = options[:only] ? @copy.instance_methods - Array(options[:only]) : []
|
21
13
|
if @unwanted.any?
|
22
14
|
@copy = @copy.dup
|
23
15
|
end
|
24
16
|
end
|
25
17
|
|
26
|
-
# @note Destructive, as it changes @copy
|
27
|
-
def override
|
28
|
-
unwanted.each do |method_name|
|
29
|
-
copy.send :remove_method, method_name
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
18
|
# @description Directly include a module whose methods you want made available in +usables.available_methods+
|
34
19
|
# Gives the module a name when including so that it shows up properly in the list of ancestors
|
35
|
-
def
|
20
|
+
def call(target)
|
36
21
|
override
|
37
22
|
if copy.name.nil?
|
38
23
|
const_name = "#{mod_name}Used"
|
@@ -43,21 +28,23 @@ module Usable
|
|
43
28
|
target.send options[:method], copy
|
44
29
|
end
|
45
30
|
|
46
|
-
# @
|
47
|
-
def
|
48
|
-
|
49
|
-
|
50
|
-
|
31
|
+
# @note Destructive, as it changes @copy
|
32
|
+
def override
|
33
|
+
unwanted.each do |method_name|
|
34
|
+
copy.send :remove_method, method_name
|
35
|
+
end
|
51
36
|
end
|
52
37
|
|
53
38
|
# @description Extends the target with the module's ClassMethod mod
|
54
39
|
def use_class_methods!(target)
|
55
|
-
return unless mod.const_defined?
|
56
|
-
target.extend mod.const_get
|
40
|
+
return unless mod.const_defined? :ClassMethods
|
41
|
+
target.extend mod.const_get :ClassMethods
|
57
42
|
end
|
58
43
|
|
59
|
-
|
60
|
-
|
44
|
+
# @description Extends the target with the module's ClassMethod mod
|
45
|
+
def use_instance_methods!(target)
|
46
|
+
return unless mod.const_defined? :InstanceMethods
|
47
|
+
target.include mod.const_get :InstanceMethods
|
61
48
|
end
|
62
49
|
|
63
50
|
def mod_name
|
data/lib/usable/version.rb
CHANGED
data/lib/usable.rb
CHANGED
@@ -35,9 +35,7 @@ module Usable
|
|
35
35
|
|
36
36
|
attr_writer :usables
|
37
37
|
|
38
|
-
# @description
|
39
|
-
# the target class. Checks if there is a module named UsableSpec within the given mods namespace and uses the instance
|
40
|
-
# methods of that as the +available_methods+
|
38
|
+
# @description Includes the given module with a set of options or block to configure it
|
41
39
|
#
|
42
40
|
# @example
|
43
41
|
#
|
@@ -49,9 +47,6 @@ module Usable
|
|
49
47
|
# end
|
50
48
|
#
|
51
49
|
# @note Hides methods
|
52
|
-
# @note We include the primary mod when there is a UsableSpec set because any instance methods defined on the mod are
|
53
|
-
# not configurable and should therefore takes precedence over those defined in the UsableSpec
|
54
|
-
#
|
55
50
|
# @param [Module] mod
|
56
51
|
# @param [Hash] options Customize the extension of the module as well as define config settings on the target
|
57
52
|
# @option [Array,Symbol] :only Limit which methods are copied from the module
|
@@ -72,12 +67,10 @@ module Usable
|
|
72
67
|
end
|
73
68
|
[scope, usables].each { |x| options.each { |k, v| x[k] = v } }
|
74
69
|
[scope, usables].each { |x| x.instance_eval &block } if block_given?
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
mod_ext.use_class_methods! self
|
80
|
-
mod_ext
|
70
|
+
ModExtender.new(mod, usable_options).call self
|
71
|
+
self.include mod.const_get(:InstanceMethods) if self.const_defined? :InstanceMethods
|
72
|
+
self.extend mod.const_get(:ClassMethods) if self.const_defined? :ClassMethods
|
73
|
+
self
|
81
74
|
end
|
82
75
|
|
83
76
|
# @return [Method] bound to the given -context-
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: usable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Buckley
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|