usable 3.3.0 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|