usable 3.6.2 → 3.7.0

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