spaced 0.2.0 → 0.3.1

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
  SHA256:
3
- metadata.gz: 66ee2fb1875b3430e05c8c415823ae7ea872a15a515b1a9c2516e0f641e85951
4
- data.tar.gz: 659031771e54f892c823e65f1b3fab58eb2ada0ceec407dbcaec146497a1062d
3
+ metadata.gz: 496fc25b4cc4a7b4d8332661ace97b36a26ee5cb9592bfeb06e1743483c47c3b
4
+ data.tar.gz: 96b4ddf6c1c5e89ead4f894ced1f71c2b2a671c7838766572f94f85462bedf82
5
5
  SHA512:
6
- metadata.gz: 212bae85a0fdcf3dbdfc717e29328fd7fd8f8401b80082fec88464e03efe1d9adf07e24bb156f9b850c65104807d7cddf53343ea2582c30d8eb164b5b3cc921f
7
- data.tar.gz: 979e2988cdefc614aeb3ff884434f747fa1e5ebce38bb1de9212695ea9b53410e60b0cd72a4ba28054ce6d4689ee4088c3e4d7e9c3053124eb819f19f663b028
6
+ metadata.gz: 4751df5962de7c88361b534dff26007baeed5a91bd8a4f796aa75d6ff31f5a48c10c8b9dc8d53528af00f9089cc8bc8865b3c97b209227cb5c9dab96f84f4c33
7
+ data.tar.gz: eb9fd26c2e44f605bf9c9f733b22263ff86a0f5fd4d8003fe1457544b3a4b2a7f08ac13b3132a7447230c3017aab6c1c4bce5d407ee4bc56d53a6fc4dd86f8ef
data/.rubocop.yml CHANGED
@@ -14,6 +14,6 @@ Style/StringLiteralsInInterpolation:
14
14
  Layout/LineLength:
15
15
  Max: 120
16
16
  Metrics/MethodLength:
17
- Max: 15
17
+ Max: 20
18
18
  Style/Documentation:
19
19
  Enabled: false
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- spaced (0.1.1)
4
+ spaced (0.3.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -1,24 +1,32 @@
1
1
  # Spaced
2
2
 
3
- Spaced is a super simple and convenient way to isolate and namespace a collection of related methods.
3
+ Spaced is a super simple and convenient way to isolate and namespace a collection of related methods into any class.
4
+
5
+ ## Usage
4
6
 
5
7
  ```ruby
6
8
  class User
7
- namespace :twitter do
8
- def create(msg)
9
- api.create_tweet msg
10
- end
11
-
12
- def read(id)
13
- api.read_tweet id
14
- end
9
+ include Spaced
15
10
 
16
- private
11
+ # Pass a black with a bunch of methods.
12
+ namespace :twitter do
13
+ def create(msg)
14
+ api.create_tweet msg
15
+ end
17
16
 
18
- def api
19
- @api ||= TwitterClient.new(api_token: parent.api_token)
20
- end
17
+ def read(id)
18
+ api.read_tweet id
21
19
  end
20
+
21
+ private
22
+
23
+ def api
24
+ @api ||= TwitterClient.new(api_token: parent.api_token)
25
+ end
26
+ end
27
+
28
+ # Or pass a predefined class, which should subclass `Spaced::Base`.
29
+ namespace :facebook, Facebook::Api
22
30
  end
23
31
 
24
32
  user = User.new
@@ -28,6 +36,37 @@ user.twitter.read(id)
28
36
 
29
37
  In the example above, `namespace` creates and initializes a new class `Twitter` and returns it from the `#twitter` method. The parent class - in this case `User` - is available at `#parent` and `@parent` from within the namespace.
30
38
 
39
+ ## Magic bang and predicate methods
40
+
41
+ If you define a `call` method in your namespaced class, you can then conveniently call that with a bang method:
42
+
43
+ ```ruby
44
+ class User < Spaced::Base
45
+ include Spaced
46
+
47
+ namespace :tweet do
48
+ def call(content)
49
+ create_tweet content
50
+ end
51
+ end
52
+ end
53
+
54
+ user = User.new
55
+ user.tweet!('my new tweet') # Will call the `#call` method with whatever arguments you give it.
56
+ ```
57
+
58
+ There is also an equivalent `predicate` method:
59
+
60
+ ```ruby
61
+ namespace :tweet do
62
+ def predicate
63
+ false
64
+ end
65
+ end
66
+ user = User.new
67
+ user.tweet? # Will call the `#predicate` method.
68
+ ```
69
+
31
70
  ## Installation
32
71
 
33
72
  Add this line to your application's Gemfile:
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Spaced
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.1"
5
5
  end
data/lib/spaced.rb CHANGED
@@ -15,14 +15,18 @@ module Spaced
15
15
 
16
16
  module ClassMethods
17
17
  def namespace(name, klass = nil, &)
18
- unless klass
18
+ if klass
19
+ raise "#{klass} must be a subclass of Spaced::Base" unless klass < Spaced::Base
20
+ else
19
21
  class_name = name.to_s.split("_").collect(&:capitalize).join
20
- klass = eval <<-RUBY, binding, __FILE__, __LINE__ + 1 # rubocop:disable Security/Eval
22
+ klass = module_eval <<-RUBY, __FILE__, __LINE__ + 1
21
23
  #{self}::#{class_name} = Class.new(Base, &) # Parent::Namespace = Class.new(Base, &)
22
24
  RUBY
23
25
  end
24
26
 
25
27
  inst_name = :"@#{name}"
28
+
29
+ # Define the memoized namespace method.
26
30
  define_method name do
27
31
  if instance_variable_defined?(inst_name)
28
32
  instance_variable_get inst_name
@@ -32,6 +36,28 @@ module Spaced
32
36
  instance_variable_set inst_name, cls
33
37
  end
34
38
  end
39
+
40
+ # Define the bang and predicate methods.
41
+ methods = klass.instance_methods(false)
42
+
43
+ if methods.include?(:call)
44
+ module_eval <<-RUBY, __FILE__, __LINE__ + 1
45
+ def #{name}!(...); #{name}.call(...); end # def user!(...); user.call(...); end
46
+ RUBY
47
+ else
48
+ define_method :"#{name}!" do
49
+ raise NoMethodError, "undefined method `#{name}!' for #<#{klass}>. Have you defined `#{klass}#call`?", caller
50
+ end
51
+ end
52
+
53
+ if methods.include?(:predicate)
54
+ define_method(:"#{name}?") { send(name).predicate }
55
+ else
56
+ define_method :"#{name}?" do
57
+ raise NoMethodError, "undefined method `#{name}?' for #<#{klass}>. Have you defined `#{klass}#predicate`?",
58
+ caller
59
+ end
60
+ end
35
61
  end
36
62
  end
37
63
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spaced
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel Moss
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-05-30 00:00:00.000000000 Z
11
+ date: 2022-10-06 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: