usable 1.1.1 → 1.2.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: 066825f3c1df23a18aed5177540f36a57e163251
4
- data.tar.gz: 1d298ec0d9ce23ab4c6850d43cbdb04cd832e591
3
+ metadata.gz: 8e995dd364713419052b4643dcc4c3fd32ad3f65
4
+ data.tar.gz: 133be5883cae3533d8bbd483f63afa53aa950b62
5
5
  SHA512:
6
- metadata.gz: 4056167e5a41c520e054f9c0e66ddee45bf3e336b5fd17b8ab8a29ff80a3a33cd9ff6eb9d79614a37632a184798301513f9b209ed22421741ba0e771374ee91e
7
- data.tar.gz: 62438f10155e987c3e1a995ac9ccf9d42d0b7905231ccca4372dc072e26e8d51cfb038bc5066ccdd1c482b5d20255ffc194a473b9ba534ccfeddb2e0a6e6fd02
6
+ metadata.gz: fa11820e33b0cf6ffdf9eeb83772dd70de4794296e7ca85039e96885d57cdf21edaef12ac7271b906ca7dba666eb2ad0ee531d11fa8ac8e86ed1d12de6d4a70a
7
+ data.tar.gz: d5c339c6300345698e10b7cac58a827f06caa55e1f683691520de0785738fdba9c592b766a2ed361843b575ee87c734b74ff2729f808ff8af16e3ef6e8b5b499
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # Usable [![Gem Version](https://badge.fury.io/rb/usable.svg)](http://badge.fury.io/rb/usable)
2
2
 
3
- A simple way to mount and configure your modules. Usable gives you control over which methods are included, and the class
4
- level config provides a safe interface for calling them.
3
+ A simple way to mount and configure your modules. Usable gives you control over which methods are included, and a simple
4
+ interface to help you call dynamic methods with confidence.
5
5
 
6
6
  ```ruby
7
- module VersionKit
7
+ module VersionMixin
8
8
  def save_version
9
9
  "Saving up to #{self.class.usable_config.max_versions} versions to #{self.class.usable_config.table_name}"
10
10
  end
@@ -13,35 +13,38 @@ module VersionKit
13
13
  "Deleting versions from #{self.class.usable_config.table_name}"
14
14
  end
15
15
  end
16
-
16
+
17
17
  class Model
18
18
  extend Usable
19
19
 
20
- usable VersionKit, only: :save_version do |config|
20
+ usable VersionMixin, only: :save_version do |config|
21
21
  config.max_versions = 10
22
22
  config.table_name = 'custom_versions'
23
23
  end
24
+
25
+ def save
26
+ self.class.usable_method(self, :save_version).call
27
+ end
24
28
  end
25
29
 
26
- >> Model.usable_config.table_name
27
- => "custom_versions"
28
- >> Model.new.save_version
29
- => "Saving up to 10 versions to custom_versions"
30
- >> Model.usable_config.available_methods[:save_version].bind(Model.new).call
31
- => "Saving up to 10 versions to custom_versions"
32
- >> Model.new.respond_to? :destroy_version
33
- => false
34
- >> Model.usable_config.available_methods[:destroy_version].bind(Model.new).call
35
- => nil
30
+ model = Model.new
31
+ model.save_version # => "Saving up to 10 versions to custom_versions"
32
+ model.destroy_version # => NoMethodError: undefined method `destroy_version' for #<Model:...
36
33
  ```
37
- What's going on here? Well `#save_versions` is now extended onto the `Model` class, but `#destroy_version` is not!
34
+ You'll notice that `#save_versions` is now included on `Model`, but `#destroy_version` isn't defined.
35
+
36
+ ## Confidently calling methods
37
+
38
+ We should all be writing [confident code](http://www.confidentruby.com/). That's why it is encouraged
39
+ to reference methods through the `usable_method` class level function. Methods passed in with the `:only` option
40
+ will always return `nil` when called.
38
41
 
39
- ## But wait, you undefined my methods?
42
+ Here's the same example as above, rewritten to call methods through the Usable interface:
40
43
 
41
- Yes. Well ... yes, at least on the copy of the module included in the target class. But, checking if an object responds
42
- to a method all time doesn't produce very [confident code](http://www.confidentruby.com/). That's why it is encouraged
43
- to reference methods through the `Model.usable_config.available_methods` hash. This way you can confidently call methods,
44
- just don't rely on the return value, because methods that are removed via `:only` will return `nil`.
44
+ ```ruby
45
+ Model.usable_method(model, :save_version).call # => "Saving up to 10 versions to custom_versions"
46
+ Model.usable_method(model, :destroy_version).call # => nil
47
+ ```
45
48
 
46
49
  ## Separate included module from configurable methods
47
50
 
@@ -52,37 +55,41 @@ conflicts will be resolved by giving precedence to the parent module.
52
55
  For example:
53
56
 
54
57
  ```ruby
55
- module VersionKit
58
+ module Mixin
59
+ def name
60
+ "defined by Mixin"
61
+ end
62
+
63
+ def from_mixin
64
+ "always here"
65
+ end
66
+
67
+ # @description Usable will apply the :only to just the methods defined by this module
56
68
  module UsableSpec
57
- def version
58
- "yo"
69
+ def from_spec
70
+ "can be excluded"
59
71
  end
60
-
72
+
61
73
  def name
62
- "nope"
74
+ "defined by UsableSpec"
63
75
  end
64
76
  end
65
-
66
- def name
67
- "yup"
68
- end
69
-
70
- def self.included(base)
71
- puts base.usable_config.available_methods[:version].bind(self).call
72
- end
73
77
  end
74
78
 
75
- >> Example = Class.new.extend Usable
76
- => Example
77
- >> Example.usable VersionKit
78
- yo
79
- => Example
80
- >> Example.new.version
81
- => "yo"
82
- >> Example.new.name
83
- => "yup"
79
+ class Example
80
+ extend Usable
81
+ usable Mixin, only: [:name, :from_spec]
82
+ end
83
+
84
+ Example.new.from_spec # => "can be excluded"
85
+ Example.new.from_mixin # => "always here"
86
+ Example.new.name # => "defined by Mixin"
87
+ Example.ancestors # => [Example, Mixin, Example::MixinUsableSpecUsed, Object, Kernel, BasicObject] (ruby -v 2.3.0)
84
88
  ```
85
89
 
90
+ Noticed that Usable assigns the modified module to a constant with the same name as the given module, but with "Used" appended.
91
+ The main module and the spec were both included, but `Mixin` was not modified, so it didn't need a new name.
92
+
86
93
  ## Installation
87
94
 
88
95
  Add this line to your application's Gemfile:
data/bin/console CHANGED
@@ -10,7 +10,7 @@ require "usable"
10
10
  # require "pry"
11
11
  # Pry.start
12
12
 
13
- module VersionKit
13
+ module VersionMixin
14
14
  def save_version
15
15
  "Saving up to #{self.class.usable_config.max_versions} versions to #{self.class.usable_config.table_name}"
16
16
  end
@@ -20,13 +20,43 @@ module VersionKit
20
20
  end
21
21
  end
22
22
 
23
+ module Mixin
24
+ def name
25
+ "defined by Mixin"
26
+ end
27
+
28
+ def from_mixin
29
+ "always here"
30
+ end
31
+
32
+ # @description Usable will apply the :only to just the methods defined by this module
33
+ module UsableSpec
34
+ def from_spec
35
+ "can be excluded"
36
+ end
37
+
38
+ def name
39
+ "defined by UsableSpec"
40
+ end
41
+ end
42
+ end
43
+
23
44
  class Model
24
45
  extend Usable
25
46
 
26
- usable VersionKit, only: :save_version do |config|
47
+ usable VersionMixin, only: :save_version do |config|
27
48
  config.max_versions = 10
28
49
  config.table_name = 'custom_versions'
29
50
  end
51
+
52
+ def save
53
+ self.class.usable_method(self, :save_version).call
54
+ end
55
+ end
56
+
57
+ class Example
58
+ extend Usable
59
+ usable Mixin, only: [:name, :from_spec]
30
60
  end
31
61
 
32
62
  require "irb"
@@ -1,3 +1,3 @@
1
1
  module Usable
2
- VERSION = "1.1.1".freeze
2
+ VERSION = "1.2.0".freeze
3
3
  end
data/lib/usable.rb CHANGED
@@ -47,4 +47,9 @@ module Usable
47
47
  usable_config.modules << mod
48
48
  send :include, mod
49
49
  end
50
+
51
+ # @return [Method] bound to the given -context-
52
+ def usable_method(context, method_name)
53
+ usable_config.available_methods[method_name].bind(context)
54
+ end
50
55
  end
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: 1.1.1
4
+ version: 1.2.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-02-15 00:00:00.000000000 Z
11
+ date: 2016-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler