dry-monads 1.3.5 → 1.4.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 +4 -4
- data/CHANGELOG.md +140 -80
- data/LICENSE +1 -1
- data/README.md +5 -4
- data/dry-monads.gemspec +30 -30
- data/lib/dry-monads.rb +1 -1
- data/lib/dry/monads.rb +2 -2
- data/lib/dry/monads/all.rb +2 -2
- data/lib/dry/monads/constants.rb +1 -1
- data/lib/dry/monads/do.rb +52 -18
- data/lib/dry/monads/do/all.rb +36 -17
- data/lib/dry/monads/either.rb +7 -7
- data/lib/dry/monads/errors.rb +5 -2
- data/lib/dry/monads/lazy.rb +15 -4
- data/lib/dry/monads/list.rb +28 -28
- data/lib/dry/monads/maybe.rb +87 -19
- data/lib/dry/monads/registry.rb +10 -10
- data/lib/dry/monads/result.rb +38 -12
- data/lib/dry/monads/result/fixed.rb +33 -24
- data/lib/dry/monads/right_biased.rb +35 -16
- data/lib/dry/monads/task.rb +20 -20
- data/lib/dry/monads/transformer.rb +2 -1
- data/lib/dry/monads/traverse.rb +7 -1
- data/lib/dry/monads/try.rb +45 -12
- data/lib/dry/monads/unit.rb +6 -2
- data/lib/dry/monads/validated.rb +20 -16
- data/lib/dry/monads/version.rb +1 -1
- data/lib/json/add/dry/monads/maybe.rb +3 -3
- metadata +18 -69
- data/.codeclimate.yml +0 -12
- data/.github/ISSUE_TEMPLATE/----please-don-t-ask-for-support-via-issues.md +0 -10
- data/.github/ISSUE_TEMPLATE/---bug-report.md +0 -30
- data/.github/ISSUE_TEMPLATE/---feature-request.md +0 -18
- data/.github/workflows/ci.yml +0 -52
- data/.github/workflows/docsite.yml +0 -34
- data/.github/workflows/sync_configs.yml +0 -56
- data/.gitignore +0 -10
- data/.rspec +0 -4
- data/.rubocop.yml +0 -101
- data/.yardopts +0 -4
- data/CODE_OF_CONDUCT.md +0 -13
- data/CONTRIBUTING.md +0 -29
- data/Gemfile +0 -19
- data/Gemfile.devtools +0 -14
- data/Rakefile +0 -8
- data/bin/.gitkeep +0 -0
- data/bin/console +0 -17
- data/bin/setup +0 -7
- data/docsite/source/case-equality.html.md +0 -42
- data/docsite/source/do-notation.html.md +0 -207
- data/docsite/source/getting-started.html.md +0 -142
- data/docsite/source/index.html.md +0 -179
- data/docsite/source/list.html.md +0 -87
- data/docsite/source/maybe.html.md +0 -146
- data/docsite/source/pattern-matching.html.md +0 -68
- data/docsite/source/result.html.md +0 -190
- data/docsite/source/task.html.md +0 -126
- data/docsite/source/tracing-failures.html.md +0 -32
- data/docsite/source/try.html.md +0 -76
- data/docsite/source/unit.html.md +0 -36
- data/docsite/source/validated.html.md +0 -88
- data/log/.gitkeep +0 -0
- data/project.yml +0 -2
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
<!--- this file is synced from dry-rb/template-gem project -->
|
1
2
|
[gem]: https://rubygems.org/gems/dry-monads
|
2
3
|
[actions]: https://github.com/dry-rb/dry-monads/actions
|
3
4
|
[codacy]: https://www.codacy.com/gh/dry-rb/dry-monads
|
@@ -7,22 +8,22 @@
|
|
7
8
|
# dry-monads [][chat]
|
8
9
|
|
9
10
|
[][gem]
|
10
|
-
[][actions]
|
11
12
|
[][codacy]
|
12
13
|
[][codacy]
|
13
14
|
[][inchpages]
|
14
15
|
|
15
16
|
## Links
|
16
17
|
|
17
|
-
* [User documentation](
|
18
|
+
* [User documentation](https://dry-rb.org/gems/dry-monads)
|
18
19
|
* [API documentation](http://rubydoc.info/gems/dry-monads)
|
19
20
|
|
20
21
|
## Supported Ruby versions
|
21
22
|
|
22
23
|
This library officially supports the following Ruby versions:
|
23
24
|
|
24
|
-
* MRI
|
25
|
-
* jruby
|
25
|
+
* MRI `>= 2.6.0`
|
26
|
+
* ~~jruby~~ `>= 9.3` (we are waiting for [2.6 support](https://github.com/jruby/jruby/issues/6161))
|
26
27
|
|
27
28
|
## License
|
28
29
|
|
data/dry-monads.gemspec
CHANGED
@@ -1,39 +1,39 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
# this file is synced from dry-rb/template-gem project
|
4
|
+
|
5
|
+
lib = File.expand_path("lib", __dir__)
|
4
6
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
-
require
|
7
|
+
require "dry/monads/version"
|
6
8
|
|
7
9
|
Gem::Specification.new do |spec|
|
8
|
-
spec.name =
|
10
|
+
spec.name = "dry-monads"
|
11
|
+
spec.authors = ["Nikita Shilnikov"]
|
12
|
+
spec.email = ["fg@flashgordon.ru"]
|
13
|
+
spec.license = "MIT"
|
9
14
|
spec.version = Dry::Monads::VERSION.dup
|
10
|
-
spec.authors = ['Nikita Shilnikov']
|
11
|
-
spec.email = ['fg@flashgordon.ru']
|
12
|
-
spec.license = 'MIT'
|
13
15
|
|
14
|
-
spec.summary =
|
16
|
+
spec.summary = "Common monads for Ruby"
|
15
17
|
spec.description = spec.summary
|
16
|
-
spec.homepage =
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
spec.
|
28
|
-
|
29
|
-
|
30
|
-
spec.
|
31
|
-
spec.
|
32
|
-
|
33
|
-
spec.
|
34
|
-
|
35
|
-
spec.add_development_dependency
|
36
|
-
spec.add_development_dependency
|
37
|
-
spec.add_development_dependency 'rake'
|
38
|
-
spec.add_development_dependency 'rspec'
|
18
|
+
spec.homepage = "https://dry-rb.org/gems/dry-monads"
|
19
|
+
spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-monads.gemspec", "lib/**/*"]
|
20
|
+
spec.bindir = "bin"
|
21
|
+
spec.executables = []
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
25
|
+
spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-monads/blob/master/CHANGELOG.md"
|
26
|
+
spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-monads"
|
27
|
+
spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-monads/issues"
|
28
|
+
|
29
|
+
spec.required_ruby_version = ">= 2.6.0"
|
30
|
+
|
31
|
+
# to update dependencies edit project.yml
|
32
|
+
spec.add_runtime_dependency "concurrent-ruby", "~> 1.0"
|
33
|
+
spec.add_runtime_dependency "dry-core", "~> 0.7"
|
34
|
+
|
35
|
+
spec.add_development_dependency "bundler"
|
36
|
+
spec.add_development_dependency "dry-types", ">= 0.1.2"
|
37
|
+
spec.add_development_dependency "rake"
|
38
|
+
spec.add_development_dependency "rspec"
|
39
39
|
end
|
data/lib/dry-monads.rb
CHANGED
data/lib/dry/monads.rb
CHANGED
data/lib/dry/monads/all.rb
CHANGED
data/lib/dry/monads/constants.rb
CHANGED
data/lib/dry/monads/do.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "dry/monads/list"
|
4
|
+
require "dry/monads/do/mixin"
|
5
|
+
require "dry/monads/constants"
|
6
6
|
|
7
7
|
module Dry
|
8
8
|
module Monads
|
@@ -12,7 +12,13 @@ module Dry
|
|
12
12
|
module Do
|
13
13
|
extend Mixin
|
14
14
|
|
15
|
-
DELEGATE = ::RUBY_VERSION <
|
15
|
+
DELEGATE = ::RUBY_VERSION < "2.7" ? "*" : "..."
|
16
|
+
|
17
|
+
VISIBILITY_WORD = {
|
18
|
+
public: "",
|
19
|
+
private: "private ",
|
20
|
+
protected: "protected "
|
21
|
+
}.freeze
|
16
22
|
|
17
23
|
# @api private
|
18
24
|
class Halt < StandardError
|
@@ -26,6 +32,25 @@ module Dry
|
|
26
32
|
end
|
27
33
|
end
|
28
34
|
|
35
|
+
# @api private
|
36
|
+
class MethodTracker < ::Module
|
37
|
+
# @api private
|
38
|
+
def initialize(tracked_methods, base, wrapper)
|
39
|
+
module_eval do
|
40
|
+
private
|
41
|
+
|
42
|
+
define_method(:method_added) do |method|
|
43
|
+
super(method)
|
44
|
+
|
45
|
+
if tracked_methods.include?(method)
|
46
|
+
visibility = Do.method_visibility(base, method)
|
47
|
+
Do.wrap_method(wrapper, method, visibility)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
29
54
|
class << self
|
30
55
|
# Generates a module that passes a block to methods
|
31
56
|
# that either unwraps a single-valued monadic value or halts
|
@@ -84,13 +109,11 @@ module Dry
|
|
84
109
|
# @param [Array<Symbol>] methods
|
85
110
|
# @return [Module]
|
86
111
|
def for(*methods)
|
87
|
-
mod = ::Module.new do
|
88
|
-
methods.each { |method_name| Do.wrap_method(self, method_name) }
|
89
|
-
end
|
90
|
-
|
91
112
|
::Module.new do
|
92
113
|
singleton_class.send(:define_method, :included) do |base|
|
114
|
+
mod = ::Module.new
|
93
115
|
base.prepend(mod)
|
116
|
+
base.extend(MethodTracker.new(methods, base, mod))
|
94
117
|
end
|
95
118
|
end
|
96
119
|
end
|
@@ -100,23 +123,34 @@ module Dry
|
|
100
123
|
super
|
101
124
|
|
102
125
|
# Actually mixes in Do::All
|
103
|
-
require
|
126
|
+
require "dry/monads/do/all"
|
104
127
|
base.include All
|
105
128
|
end
|
106
129
|
|
107
130
|
# @api private
|
108
|
-
def wrap_method(target,
|
131
|
+
def wrap_method(target, method, visibility)
|
109
132
|
target.module_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
110
|
-
def #{
|
111
|
-
if block_given?
|
112
|
-
super
|
113
|
-
else
|
114
|
-
Do.() { super { |*ms| Do.bind(ms) } }
|
115
|
-
end
|
116
|
-
end
|
133
|
+
#{VISIBILITY_WORD[visibility]} def #{method}(#{DELEGATE}) # private def create_acccount(...)
|
134
|
+
if block_given? # if block_given?
|
135
|
+
super # super
|
136
|
+
else # else
|
137
|
+
Do.() { super { |*ms| Do.bind(ms) } } # Do.() { super { |*ms| Do.bind(ms) } }
|
138
|
+
end # end
|
139
|
+
end # end
|
117
140
|
RUBY
|
118
141
|
end
|
119
142
|
|
143
|
+
# @api private
|
144
|
+
def method_visibility(mod, method)
|
145
|
+
if mod.public_method_defined?(method)
|
146
|
+
:public
|
147
|
+
elsif mod.private_method_defined?(method)
|
148
|
+
:private
|
149
|
+
else
|
150
|
+
:protected
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
120
154
|
# @api private
|
121
155
|
def coerce_to_monad(monads)
|
122
156
|
return monads if monads.size != 1
|
@@ -135,7 +169,7 @@ module Dry
|
|
135
169
|
|
136
170
|
# @api private
|
137
171
|
def halt(result)
|
138
|
-
raise Halt.new(result),
|
172
|
+
raise Halt.new(result), "", []
|
139
173
|
end
|
140
174
|
end
|
141
175
|
end
|
data/lib/dry/monads/do/all.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/monads/do"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module Monads
|
@@ -68,9 +68,10 @@ module Dry
|
|
68
68
|
tracker = self
|
69
69
|
|
70
70
|
module_eval do
|
71
|
+
private
|
72
|
+
|
71
73
|
define_method(:method_added) do |method|
|
72
74
|
super(method)
|
73
|
-
|
74
75
|
tracker.wrap_method(self, method)
|
75
76
|
end
|
76
77
|
|
@@ -93,20 +94,37 @@ module Dry
|
|
93
94
|
end
|
94
95
|
|
95
96
|
def wrap_method(target, method)
|
96
|
-
Do.
|
97
|
+
visibility = Do.method_visibility(target, method)
|
98
|
+
Do.wrap_method(wrappers[target], method, visibility)
|
97
99
|
end
|
98
100
|
end
|
99
101
|
|
100
|
-
|
101
|
-
|
102
|
-
|
102
|
+
class << self
|
103
|
+
# @api private
|
104
|
+
def included(base)
|
105
|
+
super
|
103
106
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
107
|
+
wrappers = ::Hash.new { |h, k| h[k] = ::Module.new }
|
108
|
+
tracker = MethodTracker.new(wrappers)
|
109
|
+
base.extend(tracker)
|
110
|
+
base.extend(InstanceMixin) unless base.is_a?(::Class)
|
111
|
+
wrap_defined_methods(base, wrappers[base])
|
112
|
+
end
|
108
113
|
|
109
|
-
|
114
|
+
# @api private
|
115
|
+
def wrap_defined_methods(klass, target)
|
116
|
+
klass.public_instance_methods(false).each do |m|
|
117
|
+
Do.wrap_method(target, m, :public)
|
118
|
+
end
|
119
|
+
|
120
|
+
klass.protected_instance_methods(false).each do |m|
|
121
|
+
Do.wrap_method(target, m, :protected)
|
122
|
+
end
|
123
|
+
|
124
|
+
klass.private_instance_methods(false).each do |m|
|
125
|
+
Do.wrap_method(target, m, :private)
|
126
|
+
end
|
127
|
+
end
|
110
128
|
end
|
111
129
|
|
112
130
|
# @api private
|
@@ -116,17 +134,18 @@ module Dry
|
|
116
134
|
super
|
117
135
|
|
118
136
|
wrapper = ::Module.new
|
119
|
-
object.singleton_class
|
137
|
+
eigenclass = object.singleton_class
|
138
|
+
eigenclass.prepend(wrapper)
|
120
139
|
object.define_singleton_method(:singleton_method_added) do |method|
|
121
140
|
super(method)
|
122
141
|
|
123
142
|
next if method.equal?(:singleton_method_added)
|
124
143
|
|
125
|
-
Do.
|
126
|
-
|
127
|
-
object.singleton_class.instance_methods(false).each do |m|
|
128
|
-
Do.wrap_method(wrapper, m)
|
144
|
+
visibility = Do.method_visibility(eigenclass, method)
|
145
|
+
Do.wrap_method(wrapper, method, visibility)
|
129
146
|
end
|
147
|
+
|
148
|
+
All.wrap_defined_methods(eigenclass, wrapper)
|
130
149
|
end
|
131
150
|
end
|
132
151
|
|
@@ -134,7 +153,7 @@ module Dry
|
|
134
153
|
end
|
135
154
|
end
|
136
155
|
|
137
|
-
require
|
156
|
+
require "dry/monads/registry"
|
138
157
|
register_mixin(:do, Do::All)
|
139
158
|
end
|
140
159
|
end
|
data/lib/dry/monads/either.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/core/deprecations"
|
4
4
|
|
5
|
-
Dry::Core::Deprecations.warn(
|
5
|
+
Dry::Core::Deprecations.warn("Either monad was renamed to Result", tag: :"dry-monads")
|
6
6
|
|
7
|
-
require
|
7
|
+
require "dry/monads/result"
|
8
8
|
|
9
9
|
module Dry
|
10
10
|
module Monads
|
@@ -12,7 +12,7 @@ module Dry
|
|
12
12
|
deprecate_constant :Either
|
13
13
|
|
14
14
|
class Result
|
15
|
-
extend Dry::Core::Deprecations[:
|
15
|
+
extend ::Dry::Core::Deprecations[:"dry-monads"]
|
16
16
|
|
17
17
|
deprecate :to_either, :to_result
|
18
18
|
|
@@ -24,7 +24,7 @@ module Dry
|
|
24
24
|
|
25
25
|
module Mixin
|
26
26
|
module Constructors
|
27
|
-
extend Dry::Core::Deprecations[:
|
27
|
+
extend Dry::Core::Deprecations[:"dry-monads"]
|
28
28
|
|
29
29
|
Right = Success
|
30
30
|
Left = Failure
|
@@ -51,13 +51,13 @@ module Dry
|
|
51
51
|
|
52
52
|
class Try
|
53
53
|
class Value
|
54
|
-
extend Dry::Core::Deprecations[:
|
54
|
+
extend Dry::Core::Deprecations[:"dry-monads"]
|
55
55
|
|
56
56
|
deprecate :to_either, :to_result
|
57
57
|
end
|
58
58
|
|
59
59
|
class Error
|
60
|
-
extend Dry::Core::Deprecations[:
|
60
|
+
extend Dry::Core::Deprecations[:"dry-monads"]
|
61
61
|
|
62
62
|
deprecate :to_either, :to_result
|
63
63
|
end
|
data/lib/dry/monads/errors.rb
CHANGED
@@ -4,8 +4,11 @@ module Dry
|
|
4
4
|
module Monads
|
5
5
|
# An unsuccessful result of extracting a value from a monad.
|
6
6
|
class UnwrapError < StandardError
|
7
|
-
|
8
|
-
|
7
|
+
attr_reader :receiver
|
8
|
+
|
9
|
+
def initialize(receiver)
|
10
|
+
@receiver = receiver
|
11
|
+
super("value! was called on #{receiver.inspect}")
|
9
12
|
end
|
10
13
|
end
|
11
14
|
|
data/lib/dry/monads/lazy.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "concurrent/promise"
|
4
4
|
|
5
|
-
require
|
5
|
+
require "dry/core/deprecations"
|
6
|
+
require "dry/monads/task"
|
6
7
|
|
7
8
|
module Dry
|
8
9
|
module Monads
|
@@ -11,6 +12,8 @@ module Dry
|
|
11
12
|
# computation is evaluated not more than once (compare with the built-in
|
12
13
|
# lazy assignement ||= which does not guarantee this).
|
13
14
|
class Lazy < Task
|
15
|
+
extend ::Dry::Core::Deprecations[:"dry-monads"]
|
16
|
+
|
14
17
|
class << self
|
15
18
|
# @private
|
16
19
|
def new(promise = nil, &block)
|
@@ -41,6 +44,14 @@ module Dry
|
|
41
44
|
self
|
42
45
|
end
|
43
46
|
|
47
|
+
# @return [Boolean]
|
48
|
+
def evaluated?
|
49
|
+
@promise.complete?
|
50
|
+
end
|
51
|
+
deprecate :complete?, :evaluated?
|
52
|
+
|
53
|
+
undef_method :wait
|
54
|
+
|
44
55
|
# @return [String]
|
45
56
|
def to_s
|
46
57
|
state = case promise.state
|
@@ -49,7 +60,7 @@ module Dry
|
|
49
60
|
when :rejected
|
50
61
|
"!#{promise.reason.inspect}"
|
51
62
|
else
|
52
|
-
|
63
|
+
"?"
|
53
64
|
end
|
54
65
|
|
55
66
|
"Lazy(#{state})"
|
@@ -80,7 +91,7 @@ module Dry
|
|
80
91
|
end
|
81
92
|
end
|
82
93
|
|
83
|
-
require
|
94
|
+
require "dry/monads/registry"
|
84
95
|
register_mixin(:lazy, Lazy::Mixin)
|
85
96
|
end
|
86
97
|
end
|