spaced 0.2.0 → 0.3.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
  SHA256:
3
- metadata.gz: 66ee2fb1875b3430e05c8c415823ae7ea872a15a515b1a9c2516e0f641e85951
4
- data.tar.gz: 659031771e54f892c823e65f1b3fab58eb2ada0ceec407dbcaec146497a1062d
3
+ metadata.gz: 4be5f8b778afea6200764ac30e9588cd76ebedd1e6414c3abf7c2b57fadf9fc1
4
+ data.tar.gz: 01de2584949b4f50211847ba3a2fd11081f7d2e8b30769117d6016ed665596c7
5
5
  SHA512:
6
- metadata.gz: 212bae85a0fdcf3dbdfc717e29328fd7fd8f8401b80082fec88464e03efe1d9adf07e24bb156f9b850c65104807d7cddf53343ea2582c30d8eb164b5b3cc921f
7
- data.tar.gz: 979e2988cdefc614aeb3ff884434f747fa1e5ebce38bb1de9212695ea9b53410e60b0cd72a4ba28054ce6d4689ee4088c3e4d7e9c3053124eb819f19f663b028
6
+ metadata.gz: 29031788d5ab97c24364206b47583f63d37ed9f2186b541cd10003d7cdfd94f96711d638b485823085d400301d4e8c37302b587f40d4ee1e2cb4a674c2a3e6b6
7
+ data.tar.gz: f0854fa0e2813f899fc32b85e57c72b1f44845aa4574f7c419ce5e7ba5f65ad0dfd5b07e4c6de55f2514b95da1abd51627bbec0c0363e936a650a0ace847e06b
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.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -4,26 +4,42 @@ Spaced is a super simple and convenient way to isolate and namespace a collectio
4
4
 
5
5
  ```ruby
6
6
  class User
7
- namespace :twitter do
8
- def create(msg)
9
- api.create_tweet msg
10
- end
7
+ include Spaced
11
8
 
12
- def read(id)
13
- api.read_tweet id
14
- end
9
+ # Pass a black with a bunch of methods.
10
+ namespace :twitter do
11
+ def create(msg)
12
+ api.create_tweet msg
13
+ end
14
+
15
+ def read(id)
16
+ api.read_tweet id
17
+ end
15
18
 
16
- private
19
+ def call(msg)
20
+ create msg
21
+ end
17
22
 
18
- def api
19
- @api ||= TwitterClient.new(api_token: parent.api_token)
20
- end
23
+ def predicate
24
+ subject.twitter_id?
21
25
  end
26
+
27
+ private
28
+
29
+ def api
30
+ @api ||= TwitterClient.new(api_token: parent.api_token)
31
+ end
32
+ end
33
+
34
+ # Or pass a predefined class, which should subclass `Spaced::Base`.
35
+ namespace :facebook, Facebook::Api
22
36
  end
23
37
 
24
38
  user = User.new
25
39
  id = user.twitter.create("Spaced man!")
26
40
  user.twitter.read(id)
41
+ user.twitter!("Spaced man!") # calls the `call` method.
42
+ user.twitter? # calls the `predicate` method.
27
43
  ```
28
44
 
29
45
  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.
@@ -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.0"
5
5
  end
data/lib/spaced.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "spaced/version"
4
+ require "forwardable"
4
5
 
5
6
  module Spaced
6
7
  def self.included(base)
@@ -15,7 +16,9 @@ module Spaced
15
16
 
16
17
  module ClassMethods
17
18
  def namespace(name, klass = nil, &)
18
- unless klass
19
+ if klass
20
+ raise "#{klass} must be a subclass of Spaced::Base" unless klass < Spaced::Base
21
+ else
19
22
  class_name = name.to_s.split("_").collect(&:capitalize).join
20
23
  klass = eval <<-RUBY, binding, __FILE__, __LINE__ + 1 # rubocop:disable Security/Eval
21
24
  #{self}::#{class_name} = Class.new(Base, &) # Parent::Namespace = Class.new(Base, &)
@@ -23,6 +26,8 @@ module Spaced
23
26
  end
24
27
 
25
28
  inst_name = :"@#{name}"
29
+
30
+ # Define the memoized namespace method.
26
31
  define_method name do
27
32
  if instance_variable_defined?(inst_name)
28
33
  instance_variable_get inst_name
@@ -32,6 +37,27 @@ module Spaced
32
37
  instance_variable_set inst_name, cls
33
38
  end
34
39
  end
40
+
41
+ # Define the bang and predicate methods.
42
+ methods = klass.instance_methods(false)
43
+
44
+ if methods.include?(:call) || methods.include?(:predicate)
45
+ extend Forwardable
46
+ def_delegator :"#{name}", :call, :"#{name}!" if methods.include?(:call)
47
+ def_delegator :"#{name}", :predicate, :"#{name}?" if methods.include?(:predicate)
48
+ else
49
+ unless methods.include?(:call)
50
+ define_method :"#{name}!" do
51
+ raise NoMethodError, "undefined method `#{name}!' for #<#{klass}>. Have you defined `#{klass}#call`?"
52
+ end
53
+ end
54
+
55
+ unless methods.include?(:predicate)
56
+ define_method :"#{name}?" do
57
+ raise NoMethodError, "undefined method `#{name}?' for #<#{klass}>. Have you defined `#{klass}#predicate`?"
58
+ end
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.0
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-05 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: