usable 3.6.2 → 3.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e54cf5fe16514640297183af2af12a092aaf91a6
4
- data.tar.gz: f709d8c6daec561b606ab642e87883a83a7d17b1
3
+ metadata.gz: 85a5d98a29cbcaf36c27e6d3a6589eaf70634d70
4
+ data.tar.gz: 7870c49de78b222deef406fb651fab8699b31af3
5
5
  SHA512:
6
- metadata.gz: eed3a4121398ecdf306c1bef04d04e9702d0cde1a3f3e34b9895eeaa6d9721d76b0881ec82ff47078d4f8d3edd02936c6d311c0365b6252558e376df9f86e399
7
- data.tar.gz: 70c4103c6acdedadf2c8c56ed078bcdf813e4bc33d33dba2aeb2ad5e9ffcad2debea3df677db82071f34a62dfe823e02da7d8d42e97b08a6bc310709c2732378
6
+ metadata.gz: a08a319b8131e5c14aca95d31c35694ff7092723954151a7c459659c49ae3b1968446ba36842e5291c90c4ae9379c5592d3ebae8c099a87f10dbca431f5485c9
7
+ data.tar.gz: f509d164aa06ee5cc710be5ce6f3a5b15234a80bd3377be0b9b7f1e3c8844c980e088c380e9d7d9c3ca8fb5a745a137189e4751e6dc3a384894e065bc5862dac
@@ -1,3 +1,3 @@
1
1
  module Usable
2
- VERSION = "3.6.2".freeze
2
+ VERSION = "3.7.0".freeze
3
3
  end
data/lib/usable.rb CHANGED
@@ -63,11 +63,27 @@ module Usable
63
63
  extended_constants << base unless Usable.frozen?
64
64
  end
65
65
 
66
- def inherited(base)
66
+ def self.copy_usables(context, recipient)
67
67
  unless Usable.frozen?
68
- base.usables += usables
69
- Usable.extended_constants << base
68
+ recipient.usables += context.usables
69
+ Usable.extended_constants << recipient
70
70
  end
71
+ end
72
+
73
+ def inherited(base)
74
+ Usable.copy_usables(self, base)
75
+ super
76
+ end
77
+
78
+ def extended(base)
79
+ base.extend(Usable) unless base.respond_to?(:usables)
80
+ Usable.copy_usables(self, base)
81
+ super
82
+ end
83
+
84
+ def included(base)
85
+ base.extend(Usable) unless base.respond_to?(:usables)
86
+ Usable.copy_usables(self, base)
71
87
  super
72
88
  end
73
89
 
data/usable.gemspec CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
14
14
  spec.homepage = "https://github.com/ridiculous/usable"
15
15
  spec.license = "MIT"
16
16
 
17
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.files = `git ls-files -z`.split("\x0").keep_if { |f| f =~ /usable/ and f !~ /spec\// }
18
18
  spec.bindir = "exe"
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
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.6.2
4
+ version: 3.7.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: 2017-01-24 00:00:00.000000000 Z
11
+ date: 2017-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -65,18 +65,6 @@ executables: []
65
65
  extensions: []
66
66
  extra_rdoc_files: []
67
67
  files:
68
- - ".gitignore"
69
- - ".rspec"
70
- - ".ruby-gemset"
71
- - ".ruby-version"
72
- - ".travis.yml"
73
- - CHANGELOG.md
74
- - Gemfile
75
- - LICENSE.txt
76
- - README.md
77
- - Rakefile
78
- - bin/console
79
- - bin/setup
80
68
  - lib/usable.rb
81
69
  - lib/usable/config.rb
82
70
  - lib/usable/config_multi.rb
data/.gitignore DELETED
@@ -1,11 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
10
- *.gem
11
- .byebug_history
data/.rspec DELETED
@@ -1 +0,0 @@
1
- --color
data/.ruby-gemset DELETED
@@ -1 +0,0 @@
1
- usable
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- ruby-2.4.0
data/.travis.yml DELETED
@@ -1,6 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.2.5
4
- - 2.3.3
5
- - 2.4.0
6
- before_install: gem install bundler -v 1.10.5
data/CHANGELOG.md DELETED
@@ -1,69 +0,0 @@
1
- 3.6.2 (1/23/2016)
2
- =================
3
-
4
- * Update Railtie to _always_ freeze Usable _after_ `Rails.application.eager_load!`
5
- * Add `Usable.logger` to help debugging (default level: `Logger::ERROR`)
6
-
7
- 3.6.1 (1/23/2016)
8
- =================
9
-
10
- * Fix issue with trying to modify Usable.extended_constants when freezing Usable because it may eager-load subclasses of a class that extends Usable
11
-
12
- 3.6.0 (1/19/2016)
13
- =================
14
-
15
- * NEW - Add Rails setting `usable_config.frozen` to freeze Usable in a after initialize Railtie
16
- * NEW - Add inherited hook to copy usable config to subclasses
17
-
18
- 3.5.0 (1/18/2016)
19
- =================
20
-
21
- * FIX - Can marshal Usable configs
22
- * NEW - Track extended modules and constants so they can be eagerloaded and frozen in certain environments
23
-
24
- 3.4.0 (12/22/2016)
25
- ==================
26
-
27
- * FIX - Copying usable attributes from a module to class/module works as expected
28
- * NEW - Pass `only: :constants` when mounting a module to import just the constants from a module
29
-
30
- 3.3.0 (12/4/2016)
31
- =================
32
-
33
- * FIX - `Usable::ModExtender` doesn't require the target to be "usable"
34
- * NEW - `Usable::Struct(a: :b)` creates value classes with defaults (optional `require 'usable/struct'`)
35
- * NEW - `usables.merge` converts usables to a hash and merges w/ the other
36
- * NEW - Usable::Config#initialize takes a hash to set the initial attributes
37
- * NEW - Usable politely defines `.config(&block)`
38
- * FIX - `usables.freeze` to also freeze `@spec` so errors are raised when modifying
39
-
40
- 3.2 (12/1/2016)
41
- ===============
42
-
43
- * Improve performance of reads by defining usable attributes as methods
44
- * `usables._spec` is now `usables.spec`
45
-
46
- 3.1 (11/30/2016)
47
- ================
48
-
49
- * Convert +usables+ to a hash with +to_h+
50
-
51
- 3.0 (11/4/2016)
52
- ===============
53
-
54
- * Multiple mods can be given to +usable+ simultaneously
55
- * The +usables+ method no longer accepts a block (for performance reasons)
56
- * Fix bug in Config#method_missing that was swallowing errors
57
- * Fix bug in scoping Instance and Class method mods to the target module
58
-
59
- 2.2.1 (10/14/2016)
60
- ==================
61
-
62
- * Usable config is copied correctly when extending a usable module
63
-
64
- 2.2.0 (9/30/2016)
65
- ==================
66
-
67
- * [[PR #6](https://github.com/ridiculous/usable/pull/6))] Config options accept blocks that will be lazy loaded once and memoized for future calls
68
- * [[Issue #4](https://github.com/ridiculous/usable/issues/4)] Fix bug in `Config#respond_to_missing?`
69
-
data/Gemfile DELETED
@@ -1,10 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in usable.gemspec
4
- gemspec
5
-
6
- if RUBY_VERSION >= '2.0'
7
- # gem 'object_tracker'
8
- gem 'byebug'
9
- end
10
-
data/LICENSE.txt DELETED
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2016 Ryan Buckley
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
data/README.md DELETED
@@ -1,219 +0,0 @@
1
- # Usable [![Gem Version](https://badge.fury.io/rb/usable.svg)](http://badge.fury.io/rb/usable) [![Build Status](https://travis-ci.org/ridiculous/usable.svg)](https://travis-ci.org/ridiculous/usable) [![Code Climate](https://codeclimate.com/github/ridiculous/usable/badges/gpa.svg)](https://codeclimate.com/github/ridiculous/usable)
2
-
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
-
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:
17
- ```ruby
18
- module VersionMixin
19
- extend Usable
20
-
21
- config do
22
- max_versions 25
23
- table_name 'versions'
24
- observer { Class.new }
25
- end
26
-
27
- def save_version
28
- "Saving #{usables.max_versions} #{usables.table_name}"
29
- end
30
-
31
- def destroy_version
32
- "Deleting versions from #{usables.table_name}"
33
- end
34
- end
35
- ```
36
-
37
- Include the module into a class using `usable`, which will copy over the configs:
38
- ```ruby
39
- class Model
40
- extend Usable
41
-
42
- usable VersionMixin, only: :save_version do
43
- max_versions 10
44
- end
45
-
46
- def save
47
- save_version
48
- end
49
- end
50
-
51
- model = Model.new
52
- model.save_version # => "Saving 10 versions"
53
- model.destroy_version # => NoMethodError: undefined method `destroy_version' for #<Model:...
54
- model.usables.max_versions # => 10
55
- model.usables.table_name # => "version"
56
- ```
57
-
58
- `Model` now has a `#save_versions` method but no `#destroy_version` method. Usable has effectively mixed in the given module
59
- using `include`. Ruby 2+ offers the `prepend` method, which can be used instead by specifying it as the `:method` option:
60
-
61
- ```ruby
62
- Model.usable VersionMixin, method: :prepend
63
- ```
64
-
65
- A usable module can also be extended onto a class with `method: :extend`
66
-
67
- Usable reserves the `:only` and `:method` keys. All other keys in the given hash are defined as config settings. If you really
68
- want to define a config on the target class with one of these names, you can simply define them in the block:
69
-
70
- ```ruby
71
- Model.usable VersionMixin, only: [:save_version] do
72
- only "Will be set on `Model.usables.only` and namespaced under `Model.usables.version_mixin.only`"
73
- end
74
- ```
75
-
76
- ## Configuring Modules
77
-
78
- Configuration settings defined on a "usable" module will be copied to the including class. Usable defines
79
- a `config` method on extended modules (alias for `usables`) to use for setting default configuration options:
80
-
81
- ```ruby
82
- module Mixin
83
- extend Usable
84
- config.language = :en
85
- config do
86
- country 'US'
87
- state 'Hawaii'
88
- census({
89
- population: 1_400_00,
90
- daily_visitors: 218_150
91
- })
92
- end
93
- end
94
-
95
- Model.usable Mixin
96
- Model.usables[:state] # => 'Hawaii'
97
- Model.usables.census[:daily_visitors] # => 218150
98
- ```
99
-
100
- ## Confidently calling methods
101
-
102
- We should all be writing [confident code](http://www.confidentruby.com/), which is why you might want to call configurable
103
- methods through the `usable_method` class and instance method. Methods passed in with the `:only` option
104
- will _always_ return `nil` when called. Thus, the confidence.
105
-
106
- Here's the same example as above, rewritten to call methods through the Usable interface:
107
-
108
- ```ruby
109
- Model.usable_method(model, :save_version).call # => "Saving up to 10 versions to custom_versions"
110
- model.usable_method(:save_version).call # => "Saving up to 10 versions to custom_versions"
111
- Model.usable_method(model, :destroy_version).call # => nil
112
- ```
113
-
114
- ## Module Naming Conventions
115
-
116
- Modules with the following names found within the target module's namespace will be automatically used.
117
-
118
- * `ClassMethods`
119
- * `InstanceMethods`
120
-
121
- ## Notes
122
-
123
- If the given module is modified by the `:only` option, then Usable will duplicate the module so that it doesn't mutate
124
- it globally. Duplicating a module returns an anonymous module. But anonymous mods in the ancestor list can be confusing.
125
- So Usable gives the modified module a name, which is the same name as the original module but with "Used" appended.
126
-
127
- ```ruby
128
- Mixin => MixinUsed
129
- ```
130
-
131
- ## Tips and Tricks
132
-
133
- #### __since 3.6__
134
-
135
- Eager-load and freeze usables in production Rails environments with the `frozen` setting. Note that `config.cache_classes`
136
- (Rails 3+) or `config.eager_load` (Rails 4+) must also be true, since it hooks into Rails' eager load process.
137
-
138
- ```ruby
139
- config.usable_config.frozen = true
140
- ```
141
-
142
- #### __since 3.4__
143
-
144
- Import just a module's constants:
145
-
146
- ```ruby
147
- usable ExampleMod, only: :constants
148
- ```
149
-
150
- Currently works with `usable ExampleMod, only: []` since version 2.0
151
-
152
- #### __since 3.3__ _- (not required)_
153
- The `Usable::Struct` function is available for creating value objects with defaults. If you `require "usable/struct"` the
154
- class function is available to create classes:
155
-
156
- ```ruby
157
- class Route < Usable::Struct(paths: %w[api v2 v3])
158
- end
159
-
160
- Route.usables.to_h # => {:paths=>["api", "v2", "v3"]}
161
- Route.new.paths # => ["api", "v2", "v3"]
162
- Route.new(paths: nil).paths # => nil
163
- ```
164
-
165
- #### __since version 2.0__
166
-
167
- When usable modules define the same config setting, the last one mounted takes precedence. Fortunately,
168
- Usable also "stacks" config settings by namespacing them:
169
-
170
- ```ruby
171
- module Robot
172
- extend Usable
173
- config do
174
- speak 'beep bop'
175
- end
176
- end
177
-
178
- module Human
179
- extend Usable
180
- config do
181
- speak 'Hello'
182
- end
183
- end
184
-
185
- class User
186
- extend Usable
187
- usable Human, Robot
188
- end
189
-
190
- User.usables.speak # => "beep bop"
191
- User.usables.human.speak # => "Hello"
192
- User.usables.robot.speak # => "beep bop"
193
- ```
194
-
195
- ## Production
196
-
197
- When running in production you may want to eager-load any lazily defined attributes and freeze them, ensuring thread safety.
198
- Usable provides a [railtie](http://edgeguides.rubyonrails.org/configuring.html) that can be configured to freeze Usable and
199
- and constants extended with Usable.
200
-
201
- Enable the frozen setting:
202
- ```ruby
203
- # config/production.rb
204
- Acme::Application.configure do
205
- # Freeze all +usables+ after initialize, eager-loading any lazily defined attributes
206
- config.usable_config.frozen = true
207
- end
208
- ```
209
-
210
- ## Development
211
-
212
- 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.
213
-
214
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
215
-
216
- ## Contributing
217
-
218
- Bug reports and pull requests are welcome on GitHub at https://github.com/ridiculous/usable.
219
-
data/Rakefile DELETED
@@ -1,10 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require 'rspec/core/rake_task'
3
- begin
4
- require 'rspec/scaffold'
5
- rescue LoadError
6
- nil
7
- end
8
-
9
- RSpec::Core::RakeTask.new(:spec)
10
- task default: :spec
data/bin/console DELETED
@@ -1,99 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "usable"
5
- require "usable/struct"
6
- require "byebug"
7
- require "irb"
8
-
9
- # You can add fixtures and/or initialization code here to make experimenting
10
- # with your gem easier. You can also use a different console, if you like.
11
-
12
- # (If you use this, don't forget to add pry to your Gemfile!)
13
- # require "pry"
14
- # Pry.start
15
-
16
- module VersionMixin
17
- def save_version
18
- "Saving up to #{usables.max_versions} versions to #{usables.table_name}"
19
- end
20
-
21
- def destroy_version
22
- "Deleting versions from #{usables.table_name}"
23
- end
24
- end
25
-
26
- module Mixin
27
- extend Usable
28
- config.language = :en
29
- config do
30
- country 'US'
31
- state 'Hawaii'
32
- census({
33
- population: 1_400_00,
34
- daily_visitors: 218_150
35
- })
36
- end
37
-
38
- def name
39
- "defined by Mixin"
40
- end
41
- end
42
-
43
- class Model
44
- extend Usable
45
-
46
- usable VersionMixin, only: :save_version do
47
- max_versions 10
48
- table_name 'custom_versions'
49
- end
50
-
51
- def save
52
- usable_method(:save_version).call
53
- end
54
- end
55
-
56
- module PersistenceOverride
57
- def save
58
- 'nope'
59
- end
60
- end
61
-
62
- module Nested
63
- module Extension
64
- def go
65
- 'going'
66
- end
67
- end
68
- end
69
-
70
- class Example
71
- extend Usable
72
- usable Mixin
73
- usable VersionMixin do
74
- max_versions 10
75
- model { Model }
76
- end
77
- usable Nested::Extension
78
- end
79
-
80
- Model.usable PersistenceOverride, method: 'prepend'
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
-
99
- IRB.start
data/bin/setup DELETED
@@ -1,7 +0,0 @@
1
- #!/bin/bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
-
5
- bundle install
6
-
7
- # Do any other automated setup that you need to do here