usable 3.3.0 → 3.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/CHANGELOG.md +6 -0
- data/README.md +33 -12
- data/bin/console +18 -0
- data/lib/usable/config.rb +12 -5
- data/lib/usable/config_multi.rb +5 -3
- data/lib/usable/mod_extender.rb +10 -1
- data/lib/usable/version.rb +1 -1
- 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: eb11e2617182a394ba2fcf207926152e7cb93606
|
4
|
+
data.tar.gz: 2d7c5698ddd7a8984a791c29cad205f65a0ab6ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d0835d8eff617914a7968af009e307804f638191f7025dc06a54bd8b89cdf205ea2c13a14ac92de4471f96e91ebfc1d8990d08df5ea78f5d33a42d1c7f05546
|
7
|
+
data.tar.gz: 485649445fcbc569624de03000756b61fe972686432d14c6b67db88b3f8988afc1db0109f1e6750f56b7f6c5f68b4aafeb23873b45218dc78cbf181f4aaa905b
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
3.4.0 (12/22/2016)
|
2
|
+
==================
|
3
|
+
|
4
|
+
* FIX - Copying usable attributes from a module to class/module works as expected
|
5
|
+
* NEW - Pass `only: :constants` when mounting a module to import just the constants from a module
|
6
|
+
|
1
7
|
3.3.0 (12/4/2016)
|
2
8
|
=================
|
3
9
|
|
data/README.md
CHANGED
@@ -3,7 +3,17 @@
|
|
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
|
-
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'usable'
|
12
|
+
```
|
13
|
+
|
14
|
+
## Usage
|
15
|
+
|
16
|
+
Configure a module to have "usable" defaults:
|
7
17
|
```ruby
|
8
18
|
module VersionMixin
|
9
19
|
extend Usable
|
@@ -24,7 +34,7 @@ module VersionMixin
|
|
24
34
|
end
|
25
35
|
```
|
26
36
|
|
27
|
-
Include the module into a class using `usable`, which will copy over
|
37
|
+
Include the module into a class using `usable`, which will copy over the configs:
|
28
38
|
```ruby
|
29
39
|
class Model
|
30
40
|
extend Usable
|
@@ -118,15 +128,32 @@ So Usable gives the modified module a name, which is the same name as the origin
|
|
118
128
|
Mixin => MixinUsed
|
119
129
|
```
|
120
130
|
|
121
|
-
##
|
131
|
+
## Tips and Tricks
|
122
132
|
|
123
|
-
|
133
|
+
#### __3.4__ _-(unreleased)_
|
134
|
+
|
135
|
+
Import just a module's constants:
|
124
136
|
|
125
137
|
```ruby
|
126
|
-
|
138
|
+
usable ExampleMod, only: :constants
|
127
139
|
```
|
128
140
|
|
129
|
-
|
141
|
+
Currently works with `usable ExampleMod, only: []` since version 2.0
|
142
|
+
|
143
|
+
#### __since version 3.3__ _- (not required)_
|
144
|
+
The `Usable::Struct` function is available for creating value objects with defaults. If you `require "usable/struct"` the
|
145
|
+
class function is available to create classes:
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
class Route < Usable::Struct(paths: %w[api v2 v3])
|
149
|
+
end
|
150
|
+
|
151
|
+
Route.usables.to_h # => {:paths=>["api", "v2", "v3"]}
|
152
|
+
Route.new.paths # => ["api", "v2", "v3"]
|
153
|
+
Route.new(paths: nil).paths # => nil
|
154
|
+
```
|
155
|
+
|
156
|
+
#### __since version 2.0__
|
130
157
|
|
131
158
|
When usable modules define the same config setting, the last one mounted takes precedence. Fortunately,
|
132
159
|
Usable also "stacks" config settings by namespacing them:
|
@@ -156,12 +183,6 @@ User.usables.human.speak # => "Hello"
|
|
156
183
|
User.usables.robot.speak # => "beep bop"
|
157
184
|
```
|
158
185
|
|
159
|
-
Import just a module's constants with this little trick:
|
160
|
-
|
161
|
-
```ruby
|
162
|
-
usable ExampleMod, only: []
|
163
|
-
```
|
164
|
-
|
165
186
|
## Development
|
166
187
|
|
167
188
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/bin/console
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require "bundler/setup"
|
4
4
|
require "usable"
|
5
5
|
require "usable/struct"
|
6
|
+
require "byebug"
|
6
7
|
require "irb"
|
7
8
|
|
8
9
|
# You can add fixtures and/or initialization code here to make experimenting
|
@@ -78,4 +79,21 @@ end
|
|
78
79
|
|
79
80
|
Model.usable PersistenceOverride, method: 'prepend'
|
80
81
|
|
82
|
+
def run_tests(subject)
|
83
|
+
if subject.usables.instance_variable_get(:@lazy_loads).to_a != [:model]
|
84
|
+
puts "Test @lazy_loads FAILED! Expected: #{[:model]}, Actual: #{subject.usables.instance_variable_get(:@lazy_loads)}"
|
85
|
+
end
|
86
|
+
if subject.usables.model != Model
|
87
|
+
puts "Test #model FAILED! Expected: #{Model}, Actual: #{subject.usables.model}"
|
88
|
+
end
|
89
|
+
if subject.usables.max_versions != 10
|
90
|
+
puts "Test #max_version FAILED! Expected: #{10}, Actual: #{subject.usables.max_versions}"
|
91
|
+
end
|
92
|
+
if subject.usables.model.new.save != 'nope'
|
93
|
+
puts "Test #save FAILED! Expected: 'nope', Actual: #{subject.usables.model.new.save}"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
run_tests Example
|
98
|
+
|
81
99
|
IRB.start
|
data/lib/usable/config.rb
CHANGED
@@ -8,6 +8,7 @@ module Usable
|
|
8
8
|
include ConfigRegister
|
9
9
|
include ConfigMulti
|
10
10
|
|
11
|
+
# @todo Maybe keep a list of all attributes (lazy and regular)?
|
11
12
|
def initialize(attributes = {})
|
12
13
|
@spec = OpenStruct.new(attributes)
|
13
14
|
@lazy_loads = Set.new
|
@@ -42,17 +43,23 @@ module Usable
|
|
42
43
|
end
|
43
44
|
|
44
45
|
def method_missing(key, *args, &block)
|
46
|
+
# @attributes << key.to_s
|
45
47
|
if block
|
46
48
|
@lazy_loads << key
|
47
|
-
# @attributes << key.to_s
|
48
49
|
@spec.define_singleton_method(key) { yield }
|
49
50
|
else
|
50
|
-
|
51
|
-
|
51
|
+
# Needs to be a symbol so we can consistently access @lazy_loads
|
52
|
+
key = key.to_s.tr('=', '').to_sym
|
52
53
|
if args.empty?
|
53
|
-
|
54
|
+
if @spec[key]
|
55
|
+
# Cleanup, just in case we loaded it another way (e.g. combining with another usable config)
|
56
|
+
@lazy_loads.delete key
|
57
|
+
else
|
58
|
+
@spec[key] = call_spec_method(key)
|
59
|
+
end
|
60
|
+
# Define method so we don't hit method missing again
|
54
61
|
define_singleton_method(key) { @spec[key] }
|
55
|
-
|
62
|
+
@spec[key]
|
56
63
|
else
|
57
64
|
@spec[key] = args.first
|
58
65
|
end
|
data/lib/usable/config_multi.rb
CHANGED
@@ -1,17 +1,19 @@
|
|
1
1
|
module Usable
|
2
2
|
module ConfigMulti
|
3
3
|
# It's important to define all block specs we need to lazy load
|
4
|
-
# Set block specs to nil values so it will fallback to calling the underlying singleton method defined by Config#method_missing
|
5
4
|
def +(other)
|
6
5
|
config = clone
|
7
6
|
specs = other.spec.to_h
|
8
7
|
specs.each { |key, val| config[key] = val }
|
9
|
-
methods = other.spec.singleton_methods
|
8
|
+
methods = other.spec.singleton_methods
|
9
|
+
methods.map! { |name| name.to_s.tr('=', '').to_sym }
|
10
|
+
methods.uniq!
|
11
|
+
methods -= specs.keys
|
10
12
|
methods.each do |name|
|
11
|
-
config.spec[name] = nil
|
12
13
|
config.spec.define_singleton_method(name) do
|
13
14
|
other.spec.public_method(name).call
|
14
15
|
end
|
16
|
+
config.instance_variable_get(:@lazy_loads) << name
|
15
17
|
end
|
16
18
|
config
|
17
19
|
end
|
data/lib/usable/mod_extender.rb
CHANGED
@@ -9,7 +9,7 @@ module Usable
|
|
9
9
|
@options[:method] ||= :include
|
10
10
|
@copy = mod
|
11
11
|
@name = mod.name
|
12
|
-
@unwanted =
|
12
|
+
@unwanted = find_unwanted_methods(options[:only])
|
13
13
|
if @unwanted.any?
|
14
14
|
@copy = @copy.dup
|
15
15
|
end
|
@@ -37,5 +37,14 @@ module Usable
|
|
37
37
|
"UsableMod#{Time.now.strftime('%s')}"
|
38
38
|
end
|
39
39
|
end
|
40
|
+
|
41
|
+
def find_unwanted_methods(only)
|
42
|
+
return [] unless only
|
43
|
+
if :constants == only
|
44
|
+
@copy.instance_methods
|
45
|
+
else
|
46
|
+
@copy.instance_methods - Array(only)
|
47
|
+
end
|
48
|
+
end
|
40
49
|
end
|
41
50
|
end
|
data/lib/usable/version.rb
CHANGED
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: 3.
|
4
|
+
version: 3.4.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-12-
|
11
|
+
date: 2016-12-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|