usable 2.2.1 → 3.0.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/CHANGELOG.md +13 -0
- data/README.md +50 -7
- data/lib/usable/config.rb +1 -1
- data/lib/usable/version.rb +1 -1
- data/lib/usable.rb +33 -28
- 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: 18d15fe43c88882ead95863b946d7ee496b37bff
|
4
|
+
data.tar.gz: 06d47996bebf7e130062441d55e5104f39635dbc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ffbe8e76c89a3f04eaf70dc4edc61aaa9e03f80cc06c567ec99146108515e1c2a594c7def908ac622d0483b6e90bb0f2380a309066e4c31a5cc2e836c341a2e
|
7
|
+
data.tar.gz: 35c77816de2bbf4a99bbd33fdc9c2754cafcc2ea3f39f0719b8b34315a3fb62cc66f885d8074df396a2b472b1cc902d76516eaca1e179ef7adc20fbd897e6c25
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
3.0 (11/4/2016)
|
2
|
+
===============
|
3
|
+
|
4
|
+
* Multiple mods can be given to +usable+ simultaneously
|
5
|
+
* The +usables+ method no longer accepts a block (for performance reasons)
|
6
|
+
* Fix bug in Config#method_missing that was swallowing errors
|
7
|
+
* Fix bug in scoping Instance and Class method mods to the target module
|
8
|
+
|
9
|
+
2.2.1 (10/14/2016)
|
10
|
+
==================
|
11
|
+
|
12
|
+
* Usable config is copied correctly when extending a usable module
|
13
|
+
|
1
14
|
2.2.0 (9/30/2016)
|
2
15
|
==================
|
3
16
|
|
data/README.md
CHANGED
@@ -3,12 +3,16 @@
|
|
3
3
|
Usable provides an elegant way to mount and configure your modules. Class level settings can be configured on a per module basis,
|
4
4
|
available to both the module and including class. Allows you to include only the methods you want.
|
5
5
|
|
6
|
+
Configure a module to be usable
|
6
7
|
```ruby
|
7
8
|
module VersionMixin
|
8
9
|
extend Usable
|
9
|
-
|
10
|
-
config
|
11
|
-
|
10
|
+
|
11
|
+
config do
|
12
|
+
max_versions 25
|
13
|
+
table_name 'versions'
|
14
|
+
observer { Class.new }
|
15
|
+
end
|
12
16
|
|
13
17
|
def save_version
|
14
18
|
"Saving #{usables.max_versions} #{usables.table_name}"
|
@@ -18,7 +22,10 @@ module VersionMixin
|
|
18
22
|
"Deleting versions from #{usables.table_name}"
|
19
23
|
end
|
20
24
|
end
|
25
|
+
```
|
21
26
|
|
27
|
+
Include the module into a class using `usable`, which will copy over any configuration options
|
28
|
+
```ruby
|
22
29
|
class Model
|
23
30
|
extend Usable
|
24
31
|
|
@@ -32,9 +39,12 @@ class Model
|
|
32
39
|
end
|
33
40
|
|
34
41
|
model = Model.new
|
35
|
-
model.save_version
|
36
|
-
model.destroy_version
|
42
|
+
model.save_version # => "Saving 10 versions"
|
43
|
+
model.destroy_version # => NoMethodError: undefined method `destroy_version' for #<Model:...
|
44
|
+
model.usables.max_versions # => 10
|
45
|
+
model.usables.table_name # => "version"
|
37
46
|
```
|
47
|
+
|
38
48
|
`Model` now has a `#save_versions` method but no `#destroy_version` method. Usable has effectively mixed in the given module
|
39
49
|
using `include`. Ruby 2+ offers the `prepend` method, which can be used instead by specifying it as the `:method` option:
|
40
50
|
|
@@ -42,6 +52,8 @@ using `include`. Ruby 2+ offers the `prepend` method, which can be used instead
|
|
42
52
|
Model.usable VersionMixin, method: :prepend
|
43
53
|
```
|
44
54
|
|
55
|
+
A usable module can also be extended onto a class with `method: :extend`
|
56
|
+
|
45
57
|
Usable reserves the `:only` and `:method` keys. All other keys in the given hash are defined as config settings. If you really
|
46
58
|
want to define a config on the target class with one of these names, you can simply define them in the block:
|
47
59
|
|
@@ -114,10 +126,41 @@ Add this line to your application's Gemfile:
|
|
114
126
|
gem 'usable'
|
115
127
|
```
|
116
128
|
|
117
|
-
##
|
129
|
+
## Tips and Tricks
|
130
|
+
|
131
|
+
When usable modules define the same config setting, the last one mounted takes precedence. Fortunately,
|
132
|
+
Usable also "stacks" config settings by namespacing them:
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
module Robot
|
136
|
+
extend Usable
|
137
|
+
config do
|
138
|
+
speak 'beep bop'
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
module Human
|
143
|
+
extend Usable
|
144
|
+
config do
|
145
|
+
speak 'Hello'
|
146
|
+
end
|
147
|
+
end
|
118
148
|
|
119
|
-
|
149
|
+
class User
|
150
|
+
extend Usable
|
151
|
+
usable Human, Robot
|
152
|
+
end
|
153
|
+
|
154
|
+
User.usables.speak # => "beep bop"
|
155
|
+
User.usables.human.speak # => "Hello"
|
156
|
+
User.usables.robot.speak # => "beep bop"
|
157
|
+
```
|
120
158
|
|
159
|
+
Import just a module's constants with this little trick:
|
160
|
+
|
161
|
+
```ruby
|
162
|
+
usable ExampleMod, only: []
|
163
|
+
```
|
121
164
|
|
122
165
|
## Development
|
123
166
|
|
data/lib/usable/config.rb
CHANGED
data/lib/usable/version.rb
CHANGED
data/lib/usable.rb
CHANGED
@@ -20,19 +20,21 @@ module Usable
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
else
|
23
|
+
# Define +config+ when added to a module
|
23
24
|
base.instance_eval do
|
24
25
|
def config(&block)
|
25
|
-
|
26
|
+
if block
|
27
|
+
usables.instance_eval &block
|
28
|
+
else
|
29
|
+
usables
|
30
|
+
end
|
26
31
|
end unless defined? config
|
27
32
|
end
|
28
33
|
end
|
29
34
|
end
|
30
35
|
|
31
|
-
# @description Read and write configuration options
|
32
36
|
def usables
|
33
37
|
@usables ||= Config.new
|
34
|
-
return @usables unless block_given?
|
35
|
-
@usables.instance_eval &Proc.new
|
36
38
|
end
|
37
39
|
|
38
40
|
attr_writer :usables
|
@@ -54,30 +56,33 @@ module Usable
|
|
54
56
|
# @option [Array,Symbol] :only Limit which methods are copied from the module
|
55
57
|
# @option [String,Symbol] :method (:include) The method to use for including the module
|
56
58
|
# @return self
|
57
|
-
def usable(
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
59
|
+
def usable(*args, &block)
|
60
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
61
|
+
args.each do |mod|
|
62
|
+
ModExtender.new(mod, only: options.delete(:only), method: options.delete(:method)).call self
|
63
|
+
# Define settings on @usables and on the scoped @usables
|
64
|
+
scope = Config.new
|
65
|
+
if mod.name
|
66
|
+
scope_name = mod.name.split('::').last.gsub(/\B([A-Z])([a-z_0-9])/, '_\1\2').downcase
|
67
|
+
usables[scope_name] = scope
|
68
|
+
end
|
69
|
+
if mod.respond_to? :usables
|
70
|
+
scope += mod.usables
|
71
|
+
self.usables += mod.usables
|
72
|
+
end
|
73
|
+
# any left over -options- are considered "config" settings
|
74
|
+
if options
|
75
|
+
[scope, usables].each { |x| options.each { |k, v| x[k] = v } }
|
76
|
+
end
|
77
|
+
if block_given?
|
78
|
+
[scope, usables].each { |x| x.instance_eval &block }
|
79
|
+
end
|
80
|
+
if mod.const_defined?(:InstanceMethods, false)
|
81
|
+
send :include, mod.const_get(:InstanceMethods, false)
|
82
|
+
end
|
83
|
+
if mod.const_defined?(:ClassMethods, false)
|
84
|
+
send :extend, mod.const_get(:ClassMethods, false)
|
85
|
+
end
|
81
86
|
end
|
82
87
|
self
|
83
88
|
end
|
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:
|
4
|
+
version: 3.0.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-11-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|