usable 1.4.0 → 2.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/README.md +16 -11
- data/bin/console +21 -7
- data/lib/usable/config.rb +43 -11
- data/lib/usable/mod_extender.rb +3 -3
- data/lib/usable/version.rb +1 -1
- data/lib/usable.rb +45 -11
- data/usable.gemspec +1 -1
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 248031af23fb6b13a611f3ad52aed2b485e13042
|
4
|
+
data.tar.gz: 7d43e66f04750393514a83e5cf6af8950aecd242
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f33b9468b3368318c1eb79d692e168a05de74378307e8c8006c162511f2d6636ebf9f0f186c16ea85f08e63e2217212e110a7edc0328069d9c3667c40ffb7201
|
7
|
+
data.tar.gz: ca0191741f597b8c6c948135cc121c906a36ea6586e5d1a3aea6ac36d3a6b645162eace8e908675788be19cca9d895135b646be6504ea5022494e7cac1f93296
|
data/README.md
CHANGED
@@ -1,29 +1,33 @@
|
|
1
1
|
# Usable [](http://badge.fury.io/rb/usable) [](https://travis-ci.org/ridiculous/usable) [](https://codeclimate.com/github/ridiculous/usable)
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
Usable provides an elegant way to mount and configure your modules. Class level settings can be configured on a per module basis,
|
4
|
+
available to both the module and including class. Allows you to include only the methods you want.
|
5
5
|
|
6
6
|
```ruby
|
7
7
|
module VersionMixin
|
8
|
+
extend Usable
|
9
|
+
usables[:max_versions] = 25
|
10
|
+
usables[:table_name] = 'versions'
|
11
|
+
|
8
12
|
def save_version
|
9
|
-
"Saving up to #{
|
13
|
+
"Saving up to #{usables.max_versions} versions to #{usables.table_name}"
|
10
14
|
end
|
11
15
|
|
12
16
|
def destroy_version
|
13
|
-
"Deleting versions from #{
|
17
|
+
"Deleting versions from #{usables.table_name}"
|
14
18
|
end
|
15
19
|
end
|
16
20
|
|
17
21
|
class Model
|
18
22
|
extend Usable
|
19
23
|
|
20
|
-
usable VersionMixin, only: :save_version do
|
21
|
-
|
22
|
-
|
24
|
+
usable VersionMixin, only: :save_version do
|
25
|
+
max_versions 10
|
26
|
+
table_name 'custom_versions'
|
23
27
|
end
|
24
28
|
|
25
29
|
def save
|
26
|
-
|
30
|
+
usable_method(:save_version).call
|
27
31
|
end
|
28
32
|
end
|
29
33
|
|
@@ -38,8 +42,8 @@ using `include`. Ruby 2+ offers the `prepend` method, which can be used instead
|
|
38
42
|
Model.usable VersionMixin, method: :prepend
|
39
43
|
```
|
40
44
|
|
41
|
-
Usable reserves the `:only` and `:method` keys. All other keys in the given hash are defined as config settings.
|
42
|
-
|
45
|
+
Usable reserves the `:only` and `:method` keys. All other keys in the given hash are defined as config settings. If you really
|
46
|
+
want to define a config on the target class with one of these names, you can simply define them in the block:
|
43
47
|
|
44
48
|
```ruby
|
45
49
|
Model.usable VersionMixin, only: [:save_version] do |config|
|
@@ -50,13 +54,14 @@ end
|
|
50
54
|
## Confidently calling methods
|
51
55
|
|
52
56
|
We should all be writing [confident code](http://www.confidentruby.com/), which is why you might want to call configurable
|
53
|
-
methods through the `usable_method` class
|
57
|
+
methods through the `usable_method` class and instance method. Methods passed in with the `:only` option
|
54
58
|
will _always_ return `nil` when called. Thus, the confidence.
|
55
59
|
|
56
60
|
Here's the same example as above, rewritten to call methods through the Usable interface:
|
57
61
|
|
58
62
|
```ruby
|
59
63
|
Model.usable_method(model, :save_version).call # => "Saving up to 10 versions to custom_versions"
|
64
|
+
model.usable_method(:save_version).call # => "Saving up to 10 versions to custom_versions"
|
60
65
|
Model.usable_method(model, :destroy_version).call # => nil
|
61
66
|
```
|
62
67
|
|
data/bin/console
CHANGED
@@ -12,15 +12,18 @@ require "usable"
|
|
12
12
|
|
13
13
|
module VersionMixin
|
14
14
|
def save_version
|
15
|
-
"Saving up to #{
|
15
|
+
"Saving up to #{usables.max_versions} versions to #{usables.table_name}"
|
16
16
|
end
|
17
17
|
|
18
18
|
def destroy_version
|
19
|
-
"Deleting versions from #{
|
19
|
+
"Deleting versions from #{usables.table_name}"
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
module Mixin
|
24
|
+
extend Usable
|
25
|
+
usables[:max_versions] = 20
|
26
|
+
|
24
27
|
def name
|
25
28
|
"defined by Mixin"
|
26
29
|
end
|
@@ -44,13 +47,13 @@ end
|
|
44
47
|
class Model
|
45
48
|
extend Usable
|
46
49
|
|
47
|
-
usable VersionMixin, only: :save_version do
|
48
|
-
|
49
|
-
|
50
|
+
usable VersionMixin, only: :save_version do
|
51
|
+
max_versions 10
|
52
|
+
table_name 'custom_versions'
|
50
53
|
end
|
51
54
|
|
52
55
|
def save
|
53
|
-
|
56
|
+
usable_method(:save_version).call
|
54
57
|
end
|
55
58
|
end
|
56
59
|
|
@@ -60,10 +63,21 @@ module PersistenceOverride
|
|
60
63
|
end
|
61
64
|
end
|
62
65
|
|
66
|
+
module Nested
|
67
|
+
module Extension
|
68
|
+
def go
|
69
|
+
'going'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
63
74
|
class Example
|
64
75
|
extend Usable
|
65
76
|
usable Mixin
|
66
|
-
usable VersionMixin
|
77
|
+
usable VersionMixin do
|
78
|
+
max_versions 10
|
79
|
+
end
|
80
|
+
usable Nested::Extension
|
67
81
|
end
|
68
82
|
|
69
83
|
Model.usable PersistenceOverride, method: 'prepend'
|
data/lib/usable/config.rb
CHANGED
@@ -1,27 +1,59 @@
|
|
1
1
|
module Usable
|
2
|
-
class Config
|
3
|
-
|
4
|
-
|
2
|
+
class Config
|
3
|
+
# = Class
|
4
|
+
# Store and manage configuration settings. Keep methods to a minimum since this class relies on method_missing to read
|
5
|
+
# and write to the underlying @spec object
|
6
|
+
#
|
7
|
+
|
8
|
+
def available_methods
|
9
|
+
modules.each_with_object(Hash.new(Null.instance_method(:default_method))) do |mod, result|
|
10
|
+
mod.instance_methods.each do |method_name|
|
11
|
+
result[method_name] = mod.instance_method method_name
|
12
|
+
end
|
13
|
+
end
|
5
14
|
end
|
6
15
|
|
7
16
|
def add_module(mod)
|
8
17
|
modules << mod
|
9
18
|
end
|
10
19
|
|
11
|
-
def
|
12
|
-
modules
|
13
|
-
|
14
|
-
|
15
|
-
|
20
|
+
def modules
|
21
|
+
@modules ||= []
|
22
|
+
end
|
23
|
+
|
24
|
+
def each(&block)
|
25
|
+
@spec.to_h.each(&block)
|
26
|
+
end
|
27
|
+
|
28
|
+
def spec(key, value = nil)
|
29
|
+
@spec ||= OpenStruct.new
|
30
|
+
if value
|
31
|
+
@spec[key.to_s.tr('=', '')] = value
|
32
|
+
else
|
33
|
+
@spec[key]
|
16
34
|
end
|
17
35
|
end
|
18
36
|
|
19
|
-
def
|
20
|
-
|
37
|
+
def [](key)
|
38
|
+
spec key
|
39
|
+
end
|
40
|
+
|
41
|
+
def []=(key, val)
|
42
|
+
spec key, val
|
43
|
+
end
|
44
|
+
|
45
|
+
def method_missing(method_name, *args)
|
46
|
+
spec method_name, *args
|
47
|
+
rescue
|
48
|
+
super
|
49
|
+
end
|
50
|
+
|
51
|
+
def respond_to_missing?(method_name, _private = false)
|
52
|
+
method_name.to_s.end_with?('=') || spec.respond_to?(method_name)
|
21
53
|
end
|
22
54
|
|
23
55
|
module Null
|
24
|
-
def default_method(*, &
|
56
|
+
def default_method(*, &_block)
|
25
57
|
end
|
26
58
|
end
|
27
59
|
end
|
data/lib/usable/mod_extender.rb
CHANGED
@@ -30,7 +30,7 @@ module Usable
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
# @description Directly include a module whose methods you want made available in +
|
33
|
+
# @description Directly include a module whose methods you want made available in +usables.available_methods+
|
34
34
|
# Gives the module a name when including so that it shows up properly in the list of ancestors
|
35
35
|
def use!(target)
|
36
36
|
override
|
@@ -39,14 +39,14 @@ module Usable
|
|
39
39
|
target.send :remove_const, const_name if target.const_defined? const_name, false
|
40
40
|
target.const_set const_name, copy
|
41
41
|
end
|
42
|
-
target.
|
42
|
+
target.usables.add_module copy
|
43
43
|
target.send options[:method], copy
|
44
44
|
end
|
45
45
|
|
46
46
|
# @description Includes or prepends the original module onto the target
|
47
47
|
def use_original!(target)
|
48
48
|
return unless has_spec?
|
49
|
-
target.
|
49
|
+
target.usables.add_module mod
|
50
50
|
target.send options[:method], mod
|
51
51
|
end
|
52
52
|
|
data/lib/usable/version.rb
CHANGED
data/lib/usable.rb
CHANGED
@@ -5,10 +5,35 @@ require 'usable/mod_extender'
|
|
5
5
|
require 'usable/config'
|
6
6
|
|
7
7
|
module Usable
|
8
|
-
|
9
|
-
|
8
|
+
|
9
|
+
# @description Define an instance level version of +usables+
|
10
|
+
def self.extended(base)
|
11
|
+
base.class_eval do
|
12
|
+
def usables
|
13
|
+
self.class.usables
|
14
|
+
end
|
15
|
+
|
16
|
+
def usable_method(method_name)
|
17
|
+
self.class.usable_method(self, method_name)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
unless base.is_a? Class
|
21
|
+
base.instance_eval do
|
22
|
+
def config(&block)
|
23
|
+
usables(&block)
|
24
|
+
end unless defined? config
|
25
|
+
end
|
26
|
+
end
|
10
27
|
end
|
11
|
-
|
28
|
+
|
29
|
+
# @description Read and write configuration options
|
30
|
+
def usables
|
31
|
+
@usables ||= Config.new
|
32
|
+
return @usables unless block_given?
|
33
|
+
@usables.instance_eval &Proc.new
|
34
|
+
end
|
35
|
+
|
36
|
+
attr_writer :usables
|
12
37
|
|
13
38
|
# @description Configures the +available_methods+ of a module using the given options or block and then includes it on
|
14
39
|
# the target class. Checks if there is a module named UsableSpec within the given mods namespace and uses the instance
|
@@ -18,8 +43,8 @@ module Usable
|
|
18
43
|
#
|
19
44
|
# class Example
|
20
45
|
# extend Usable
|
21
|
-
# usable Mixin, only: [:foo, :bar] do
|
22
|
-
#
|
46
|
+
# usable Mixin, only: [:foo, :bar] do
|
47
|
+
# baz "Available as `Example.usables.baz` or `Example.usables.mixin.baz`"
|
23
48
|
# end
|
24
49
|
# end
|
25
50
|
#
|
@@ -32,13 +57,22 @@ module Usable
|
|
32
57
|
# @option [Array,Symbol] :only Limit which methods are copied from the module
|
33
58
|
# @option [String,Symbol] :method (:include) The method to use for including the module
|
34
59
|
# @return [ModExtender] containing the original and modified module
|
35
|
-
def usable(mod, options = {})
|
60
|
+
def usable(mod, options = {}, &block)
|
36
61
|
usable_options = { only: options.delete(:only), method: options.delete(:method) }
|
37
|
-
|
38
|
-
|
62
|
+
# Define settings on @usables and on the scoped @usables
|
63
|
+
scope = Config.new
|
64
|
+
if mod.name
|
65
|
+
scope_name = mod.name.split('::').last.gsub(/\B([A-Z])([a-z_0-9])/, '_\1\2').downcase
|
66
|
+
usables[scope_name] = scope
|
67
|
+
end
|
68
|
+
if mod.respond_to? :usables
|
69
|
+
mod.usables.each do |k, v|
|
70
|
+
[scope, usables].each { |x| x.spec k, v }
|
71
|
+
end
|
39
72
|
end
|
40
|
-
options.each { |k, v|
|
41
|
-
|
73
|
+
[scope, usables].each { |x| options.each { |k, v| x[k] = v } }
|
74
|
+
[scope, usables].each { |x| x.instance_eval &block } if block_given?
|
75
|
+
# Include module
|
42
76
|
mod_ext = ModExtender.new mod, usable_options
|
43
77
|
mod_ext.use! self
|
44
78
|
mod_ext.use_original! self
|
@@ -48,6 +82,6 @@ module Usable
|
|
48
82
|
|
49
83
|
# @return [Method] bound to the given -context-
|
50
84
|
def usable_method(context, method_name)
|
51
|
-
|
85
|
+
usables.available_methods[method_name].bind(context)
|
52
86
|
end
|
53
87
|
end
|
data/usable.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ["arebuckley@gmail.com"]
|
11
11
|
|
12
12
|
spec.summary = %q{Mounts and configures modules}
|
13
|
-
spec.description = %q{
|
13
|
+
spec.description = %q{Usable provides an elegant way to mount and configure your modules}
|
14
14
|
spec.homepage = "https://github.com/ridiculous/usable"
|
15
15
|
spec.license = "MIT"
|
16
16
|
|
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: 2.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-04-
|
11
|
+
date: 2016-04-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -58,8 +58,7 @@ dependencies:
|
|
58
58
|
- - "<"
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: '4'
|
61
|
-
description:
|
62
|
-
control over which methods are included.
|
61
|
+
description: Usable provides an elegant way to mount and configure your modules
|
63
62
|
email:
|
64
63
|
- arebuckley@gmail.com
|
65
64
|
executables: []
|