direct 2.0.0 → 2.0.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 +4 -4
- data/CHANGELOG.md +7 -0
- data/LICENSE.txt +1 -1
- data/README.md +11 -1
- data/Rakefile +1 -1
- data/lib/direct/exception_handler.rb +31 -0
- data/lib/direct/executable.rb +35 -19
- data/lib/direct/group.rb +6 -4
- data/lib/direct/strict_executable.rb +10 -67
- data/lib/direct/version.rb +1 -1
- data/lib/direct.rb +11 -9
- metadata +5 -10
- data/.gitignore +0 -10
- data/.travis.yml +0 -28
- data/Gemfile +0 -8
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/direct.gemspec +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c4b78452caed73b8ce6c197b9825690120664cfedf0a695e0b8dee7d3f93e9e
|
4
|
+
data.tar.gz: d16639349d3041cc46fd0aa8edf6cc6565e24ff70b97dd275bc6c4dbeba1c853
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2193d4a0199deb76f94bdcb22fe6042d393a32a0a23581f6957f066d6609ad51e8590436a284fa818a939b3fcd00aa495724d229d9af65c18e9dd86bc0e670ff
|
7
|
+
data.tar.gz: cd31472b4a110ceeab0cff5af7700314b71e10f911b12a426491acc94019879d92374cefdc301cc258cf3c5197f097bc9d32ae8e5209569dd7102f26131a6fe8
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## Version 2.0.1
|
2
|
+
|
3
|
+
Introduce an ExceptionHandler to allow for multiple exception blocks
|
4
|
+
Drop Ruby 2.6 support
|
5
|
+
Fix bug where strict_defer was not accepting callable and object arguments.
|
6
|
+
Drop Ruby 2.5 and below
|
7
|
+
|
1
8
|
## Version 2.0.0
|
2
9
|
|
3
10
|
A bug in deferred execution did not return the success/failure results. Fixes test names that cause a collision and incorrect test scenarios.
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -34,7 +34,7 @@ SomeClass.new.procedure.success{ |deferred_object, result, object|
|
|
34
34
|
puts "it worked!"
|
35
35
|
}.failure { |deferred_object, result, object|
|
36
36
|
puts "it failed :-("
|
37
|
-
}.exception{ |deferred_object, exception, object|
|
37
|
+
}.exception { |deferred_object, exception, object|
|
38
38
|
puts "Oh no! An exception was raised!"
|
39
39
|
}.execute
|
40
40
|
```
|
@@ -51,6 +51,16 @@ SomeClass.new.procedure.success{ |deferred_object, result, object|
|
|
51
51
|
}.execute
|
52
52
|
```
|
53
53
|
|
54
|
+
You can also handle different exceptions with different blocks:
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
SomeClass.new.procedure.exception(SomeLibrary::SomeSpecialError){ |deferred_object, exception, object|
|
58
|
+
puts "Oh no! A Special Error!"
|
59
|
+
}.exception(ArgumentError){ |deferred_object, exception, object|
|
60
|
+
puts "Oops! The arguments are wrong!"
|
61
|
+
}.execute
|
62
|
+
```
|
63
|
+
|
54
64
|
The `defer` method uses built-in classes but you can build your own to manage executing named blocks
|
55
65
|
|
56
66
|
```ruby
|
data/Rakefile
CHANGED
@@ -0,0 +1,31 @@
|
|
1
|
+
module Direct
|
2
|
+
# This class monitors exception types with related blocks.
|
3
|
+
class ExceptionHandler
|
4
|
+
def initialize
|
5
|
+
@handlers = {}
|
6
|
+
end
|
7
|
+
|
8
|
+
# All classes, including StandardError, for which this object
|
9
|
+
# maintains a block to execute.
|
10
|
+
def classes
|
11
|
+
[StandardError, @handlers.keys.flatten].flatten
|
12
|
+
end
|
13
|
+
|
14
|
+
# Pass a single or multiple exception classes and the block
|
15
|
+
# to be used to handle them.
|
16
|
+
def monitor(*classes, &block)
|
17
|
+
@handlers[classes.flatten] = block
|
18
|
+
end
|
19
|
+
|
20
|
+
# This will find the first handler given to `monitor` which matches
|
21
|
+
# the provided exception's class and will execute it with the
|
22
|
+
# deferred object, the exception object, and any given object to the
|
23
|
+
# deferred object.
|
24
|
+
def call(deferred, exception, object)
|
25
|
+
if_none = proc { raise "No handler for this exception: #{exception.class}!" }
|
26
|
+
result = @handlers.find(if_none) { |key, val| key.include?(exception.class) }
|
27
|
+
|
28
|
+
result.last.call(deferred, exception, object)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/direct/executable.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require "direct/exception_handler"
|
2
|
+
|
1
3
|
module Direct
|
2
4
|
class Executable
|
3
5
|
include Direct.allow_missing_directions
|
@@ -40,18 +42,20 @@ module Direct
|
|
40
42
|
# puts "The #{thing} did something!"
|
41
43
|
# }.execute
|
42
44
|
#
|
43
|
-
def initialize(callable=nil,
|
44
|
-
@object = object
|
45
|
+
def initialize(callable = nil, *args, **kwargs, &block)
|
46
|
+
@object = kwargs.delete(:object)
|
47
|
+
@args = args
|
48
|
+
@kwargs = kwargs
|
49
|
+
@exception_handler = kwargs.delete(:exception_handler) || ExceptionHandler.new
|
45
50
|
@execution = callable || block
|
46
|
-
@exception_classes = [StandardError]
|
47
51
|
end
|
48
|
-
attr_reader :execution, :
|
52
|
+
attr_reader :execution, :exception_handler, :object, :args, :kwargs
|
49
53
|
|
50
54
|
# Tell the object what to do for a success path
|
51
55
|
#
|
52
56
|
# Returns itself
|
53
57
|
#
|
54
|
-
def success(callable=nil, &block)
|
58
|
+
def success(callable = nil, &block)
|
55
59
|
direct(:success, (callable || block))
|
56
60
|
self
|
57
61
|
end
|
@@ -60,7 +64,7 @@ module Direct
|
|
60
64
|
#
|
61
65
|
# Returns itself
|
62
66
|
#
|
63
|
-
def failure(callable=nil, &block)
|
67
|
+
def failure(callable = nil, &block)
|
64
68
|
direct(:failure, (callable || block))
|
65
69
|
self
|
66
70
|
end
|
@@ -81,18 +85,22 @@ module Direct
|
|
81
85
|
# }
|
82
86
|
#
|
83
87
|
def exception(*classes, &block)
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
direct(:exception,
|
88
|
+
classes = [StandardError] if classes.empty?
|
89
|
+
exception_handler.monitor(classes, &block)
|
90
|
+
|
91
|
+
direct(:exception, exception_handler)
|
88
92
|
self
|
89
93
|
end
|
90
94
|
|
95
|
+
def exception_classes
|
96
|
+
exception_handler.classes
|
97
|
+
end
|
98
|
+
|
91
99
|
def run_exception_block(exception)
|
92
100
|
if __directions.key?(:exception)
|
93
|
-
as_directed(:exception, exception, object)
|
101
|
+
as_directed(:exception, exception, object, *args, **kwargs)
|
94
102
|
else
|
95
|
-
as_directed(:failure, exception, object)
|
103
|
+
as_directed(:failure, exception, object, *args, **kwargs)
|
96
104
|
end
|
97
105
|
end
|
98
106
|
private :run_exception_block
|
@@ -102,15 +110,23 @@ module Direct
|
|
102
110
|
# provided to the exception path.
|
103
111
|
#
|
104
112
|
def value
|
105
|
-
|
106
|
-
if result
|
107
|
-
as_directed(:success, result, object) || result
|
108
|
-
else
|
109
|
-
as_directed(:failure, result, object) || result
|
110
|
-
end
|
113
|
+
trigger_directions
|
111
114
|
rescue *exception_classes => exception
|
112
115
|
run_exception_block(exception)
|
113
116
|
end
|
114
|
-
|
117
|
+
alias_method :execute, :value
|
118
|
+
|
119
|
+
def trigger_directions
|
120
|
+
result = execution.call
|
121
|
+
if result
|
122
|
+
as_directed(:success, result, object, *args, **kwargs)
|
123
|
+
else
|
124
|
+
as_directed(:failure, result, object, *args, **kwargs)
|
125
|
+
end || result
|
126
|
+
end
|
127
|
+
private :trigger_directions
|
128
|
+
|
115
129
|
end
|
130
|
+
|
131
|
+
private_constant :Executable
|
116
132
|
end
|
data/lib/direct/group.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
-
require
|
1
|
+
require "concurrent"
|
2
2
|
module Direct
|
3
3
|
class Group
|
4
4
|
def initialize
|
5
|
-
@map = Concurrent::Map.new{|collection, key|
|
6
|
-
collection.put(key, Concurrent::
|
5
|
+
@map = Concurrent::Map.new { |collection, key|
|
6
|
+
collection.put(key, Concurrent::Set.new)
|
7
7
|
}
|
8
8
|
end
|
9
9
|
|
10
10
|
attr_reader :map
|
11
11
|
private :map
|
12
12
|
|
13
|
-
def store(key, callable=nil, &block)
|
13
|
+
def store(key, callable = nil, &block)
|
14
14
|
map[key] << (callable || block)
|
15
15
|
self
|
16
16
|
end
|
@@ -31,4 +31,6 @@ module Direct
|
|
31
31
|
map.keys.inspect
|
32
32
|
end
|
33
33
|
end
|
34
|
+
|
35
|
+
private_constant :Group
|
34
36
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Direct
|
2
|
-
class StrictExecutable
|
2
|
+
class StrictExecutable < Executable
|
3
3
|
include Direct
|
4
4
|
|
5
5
|
# It is intended that you initialize objects via Direct.strict_defer
|
@@ -42,77 +42,20 @@ module Direct
|
|
42
42
|
# puts "#{thing} failed!"
|
43
43
|
# }.execute
|
44
44
|
#
|
45
|
-
def initialize(callable=nil, object: nil, &block)
|
46
|
-
@object = object
|
47
|
-
@execution = callable || block
|
48
|
-
@exception_classes = [StandardError]
|
49
|
-
end
|
50
|
-
attr_reader :execution, :exception_classes, :object
|
51
|
-
|
52
|
-
# Tell the object what to do for a success path
|
53
|
-
#
|
54
|
-
# Returns itself
|
55
|
-
#
|
56
|
-
def success(callable=nil, &block)
|
57
|
-
direct(:success, (callable || block))
|
58
|
-
self
|
59
|
-
end
|
60
|
-
|
61
|
-
# Tell the object what to do for a failure path
|
62
|
-
#
|
63
|
-
# Returns itself
|
64
|
-
#
|
65
|
-
def failure(callable=nil, &block)
|
66
|
-
direct(:failure, (callable || block))
|
67
|
-
self
|
68
|
-
end
|
69
|
-
|
70
|
-
# Tell the object what to do for an exception path.
|
71
|
-
#
|
72
|
-
# You may optionally provide a list of modules rescued by
|
73
|
-
# the value method in the case of an exception.
|
74
|
-
#
|
75
|
-
# Returns itself
|
76
|
-
#
|
77
|
-
# Example:
|
78
|
-
#
|
79
|
-
# Direct.strict_defer {
|
80
|
-
# # something...
|
81
|
-
# }.exception(NoMethodError) { |deferred, exception, object|
|
82
|
-
# ExceptionNotifier.notify(exception)
|
83
|
-
# }
|
84
|
-
#
|
85
|
-
def exception(*classes, &block)
|
86
|
-
unless classes.empty?
|
87
|
-
@exception_classes = classes
|
88
|
-
end
|
89
|
-
direct(:exception, block)
|
90
|
-
self
|
91
|
-
end
|
92
|
-
|
93
|
-
def run_exception_block(exception)
|
94
|
-
if __directions.key?(:exception)
|
95
|
-
as_directed(:exception, exception, object)
|
96
|
-
else
|
97
|
-
as_directed(:failure, exception, object)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
private :run_exception_block
|
101
45
|
|
102
|
-
#
|
103
|
-
#
|
104
|
-
# provided to the exception path.
|
46
|
+
# Override the behavior of the parent class to *not* fall back to the
|
47
|
+
# result.
|
105
48
|
#
|
106
|
-
def
|
107
|
-
result = execution.
|
49
|
+
def trigger_directions
|
50
|
+
result = execution.call
|
108
51
|
if result
|
109
|
-
as_directed(:success, result)
|
52
|
+
as_directed(:success, result, object, *args, **kwargs)
|
110
53
|
else
|
111
|
-
as_directed(:failure, result)
|
54
|
+
as_directed(:failure, result, object, *args, **kwargs)
|
112
55
|
end
|
113
|
-
rescue *exception_classes => exception
|
114
|
-
run_exception_block(exception)
|
115
56
|
end
|
116
|
-
|
57
|
+
private :trigger_directions
|
117
58
|
end
|
59
|
+
|
60
|
+
private_constant :StrictExecutable
|
118
61
|
end
|
data/lib/direct/version.rb
CHANGED
data/lib/direct.rb
CHANGED
@@ -52,8 +52,8 @@ module Direct
|
|
52
52
|
# failure{|result| puts "it failed!" }.
|
53
53
|
# value
|
54
54
|
#
|
55
|
-
def self.strict_defer(&block)
|
56
|
-
StrictExecutable.new(&block)
|
55
|
+
def self.strict_defer(callable = nil, *args, object: nil, **kwargs, &block)
|
56
|
+
StrictExecutable.new(callable, *args, object: object, **kwargs, &block)
|
57
57
|
end
|
58
58
|
|
59
59
|
# Wrap a block of code to return an object for handling
|
@@ -68,8 +68,8 @@ module Direct
|
|
68
68
|
# end
|
69
69
|
# do_it.value
|
70
70
|
#
|
71
|
-
def self.defer(*args, object: nil, &block)
|
72
|
-
Executable.new(*args, object: object, &block)
|
71
|
+
def self.defer(callable = nil, *args, object: nil, **kwargs, &block)
|
72
|
+
Executable.new(callable, *args, object: object, **kwargs, &block)
|
73
73
|
end
|
74
74
|
|
75
75
|
# Tell the object what to do in a given scenario.
|
@@ -85,9 +85,9 @@ module Direct
|
|
85
85
|
# puts "it failed!"
|
86
86
|
# }.do_it
|
87
87
|
#
|
88
|
-
# Your blocks will always receive the object itself as the first argument.
|
88
|
+
# Your blocks will *always* receive the object itself as the first argument.
|
89
89
|
#
|
90
|
-
def direct(key, callable=nil, &block)
|
90
|
+
def direct(key, callable = nil, &block)
|
91
91
|
__directions.store(key, callable || block)
|
92
92
|
self
|
93
93
|
end
|
@@ -103,10 +103,12 @@ module Direct
|
|
103
103
|
# end
|
104
104
|
#
|
105
105
|
# This will raise an error if the provided key is not found
|
106
|
-
|
106
|
+
#
|
107
|
+
# The current value for self will be sent as the first argument to the block
|
108
|
+
def as_directed(key, ...)
|
107
109
|
return if allow_missing_directions? && __directions.empty?
|
108
110
|
__directions.fetch(key).map do |block|
|
109
|
-
block.call(self,
|
111
|
+
block.call(self, ...)
|
110
112
|
end
|
111
113
|
rescue KeyError
|
112
114
|
return if allow_missing_directions?
|
@@ -120,6 +122,6 @@ module Direct
|
|
120
122
|
end
|
121
123
|
|
122
124
|
def __directions
|
123
|
-
@__directions ||=
|
125
|
+
@__directions ||= Group.new
|
124
126
|
end
|
125
127
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: direct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jim Gay
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-12-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -31,18 +31,13 @@ executables: []
|
|
31
31
|
extensions: []
|
32
32
|
extra_rdoc_files: []
|
33
33
|
files:
|
34
|
-
- ".gitignore"
|
35
|
-
- ".travis.yml"
|
36
34
|
- CHANGELOG.md
|
37
35
|
- CODE_OF_CONDUCT.md
|
38
|
-
- Gemfile
|
39
36
|
- LICENSE.txt
|
40
37
|
- README.md
|
41
38
|
- Rakefile
|
42
|
-
- bin/console
|
43
|
-
- bin/setup
|
44
|
-
- direct.gemspec
|
45
39
|
- lib/direct.rb
|
40
|
+
- lib/direct/exception_handler.rb
|
46
41
|
- lib/direct/executable.rb
|
47
42
|
- lib/direct/group.rb
|
48
43
|
- lib/direct/strict_executable.rb
|
@@ -59,14 +54,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
59
54
|
requirements:
|
60
55
|
- - ">="
|
61
56
|
- !ruby/object:Gem::Version
|
62
|
-
version: '
|
57
|
+
version: '2.7'
|
63
58
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
59
|
requirements:
|
65
60
|
- - ">="
|
66
61
|
- !ruby/object:Gem::Version
|
67
62
|
version: '0'
|
68
63
|
requirements: []
|
69
|
-
rubygems_version: 3.1
|
64
|
+
rubygems_version: 3.4.1
|
70
65
|
signing_key:
|
71
66
|
specification_version: 4
|
72
67
|
summary: Direct objects to perform arbitrary blocks by name
|
data/.gitignore
DELETED
data/.travis.yml
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
sudo: false
|
2
|
-
before_install:
|
3
|
-
- gem update --system
|
4
|
-
- gem install bundler
|
5
|
-
language: ruby
|
6
|
-
cache: bundler
|
7
|
-
rvm:
|
8
|
-
- 2.3.6
|
9
|
-
- 2.4.4
|
10
|
-
- 2.5.3
|
11
|
-
- 2.6.1
|
12
|
-
- ruby-head
|
13
|
-
- jruby-head
|
14
|
-
env:
|
15
|
-
global:
|
16
|
-
- CC_TEST_REPORTER_ID=3c4cb48bcc4e29bb3292e99b7736c6dd7c13d0f6a908785e164d03666f5070cc
|
17
|
-
matrix:
|
18
|
-
allow_failures:
|
19
|
-
- rvm: ruby-head
|
20
|
-
- rvm: jruby-head
|
21
|
-
before_script:
|
22
|
-
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
23
|
-
- chmod +x ./cc-test-reporter
|
24
|
-
- ./cc-test-reporter before-build
|
25
|
-
script:
|
26
|
-
- bundle exec rake
|
27
|
-
after_script:
|
28
|
-
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
data/Gemfile
DELETED
data/bin/console
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require "bundler/setup"
|
4
|
-
require "direct"
|
5
|
-
|
6
|
-
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
-
# with your gem easier. You can also use a different console, if you like.
|
8
|
-
|
9
|
-
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
-
# require "pry"
|
11
|
-
# Pry.start
|
12
|
-
|
13
|
-
require "irb"
|
14
|
-
IRB.start(__FILE__)
|
data/bin/setup
DELETED
data/direct.gemspec
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path("../lib", __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require "direct/version"
|
5
|
-
|
6
|
-
Gem::Specification.new do |spec|
|
7
|
-
spec.name = "direct"
|
8
|
-
spec.version = Direct::VERSION
|
9
|
-
spec.authors = ["Jim Gay"]
|
10
|
-
spec.email = ["jim@saturnflyer.com"]
|
11
|
-
|
12
|
-
spec.summary = %q{Direct objects to perform arbitrary blocks by name}
|
13
|
-
spec.description = %q{Direct objects to perform arbitrary blocks by name}
|
14
|
-
spec.homepage = "https://github.com/saturnflyer/direct"
|
15
|
-
spec.license = "MIT"
|
16
|
-
|
17
|
-
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
-
f.match(%r{^(test|spec|features)/})
|
19
|
-
end
|
20
|
-
spec.bindir = "exe"
|
21
|
-
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
-
spec.require_paths = ["lib"]
|
23
|
-
|
24
|
-
spec.add_dependency "concurrent-ruby", ">= 1.0"
|
25
|
-
end
|