dry-monads 1.3.2 → 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 +157 -73
- data/LICENSE +1 -1
- data/README.md +18 -38
- data/dry-monads.gemspec +32 -30
- data/lib/dry-monads.rb +3 -1
- data/lib/dry/monads.rb +4 -2
- data/lib/dry/monads/all.rb +4 -2
- data/lib/dry/monads/constants.rb +1 -1
- data/lib/dry/monads/conversion_stubs.rb +2 -0
- data/lib/dry/monads/curry.rb +2 -0
- data/lib/dry/monads/do.rb +55 -17
- data/lib/dry/monads/do/all.rb +39 -17
- data/lib/dry/monads/do/mixin.rb +2 -0
- data/lib/dry/monads/either.rb +9 -7
- data/lib/dry/monads/errors.rb +8 -3
- data/lib/dry/monads/lazy.rb +19 -6
- data/lib/dry/monads/list.rb +31 -30
- data/lib/dry/monads/maybe.rb +90 -19
- data/lib/dry/monads/registry.rb +15 -12
- data/lib/dry/monads/result.rb +42 -15
- data/lib/dry/monads/result/fixed.rb +35 -24
- data/lib/dry/monads/right_biased.rb +45 -24
- data/lib/dry/monads/task.rb +25 -22
- data/lib/dry/monads/transformer.rb +4 -1
- data/lib/dry/monads/traverse.rb +9 -1
- data/lib/dry/monads/try.rb +51 -13
- data/lib/dry/monads/unit.rb +6 -2
- data/lib/dry/monads/validated.rb +27 -20
- data/lib/dry/monads/version.rb +3 -1
- data/lib/json/add/dry/monads/maybe.rb +4 -3
- metadata +27 -75
- 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 -34
- data/.github/ISSUE_TEMPLATE/---feature-request.md +0 -18
- data/.github/workflows/ci.yml +0 -74
- data/.github/workflows/docsite.yml +0 -34
- data/.github/workflows/sync_configs.yml +0 -34
- data/.gitignore +0 -10
- data/.rspec +0 -4
- data/.rubocop.yml +0 -89
- data/.yardopts +0 -4
- data/CODE_OF_CONDUCT.md +0 -13
- data/CONTRIBUTING.md +0 -29
- data/Gemfile +0 -23
- data/Rakefile +0 -6
- data/bin/console +0 -16
- 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/LICENSE
CHANGED
data/README.md
CHANGED
|
@@ -1,50 +1,30 @@
|
|
|
1
|
-
|
|
1
|
+
<!--- this file is synced from dry-rb/template-gem project -->
|
|
2
2
|
[gem]: https://rubygems.org/gems/dry-monads
|
|
3
|
-
[
|
|
4
|
-
[
|
|
5
|
-
[inch]: http://inch-ci.org/github/dry-rb/dry-monads
|
|
3
|
+
[actions]: https://github.com/dry-rb/dry-monads/actions
|
|
4
|
+
[codacy]: https://www.codacy.com/gh/dry-rb/dry-monads
|
|
6
5
|
[chat]: https://dry-rb.zulipchat.com
|
|
6
|
+
[inchpages]: http://inch-ci.org/github/dry-rb/dry-monads
|
|
7
7
|
|
|
8
8
|
# dry-monads [][chat]
|
|
9
9
|
|
|
10
|
-
[][gem]
|
|
11
|
+
[][actions]
|
|
12
|
+
[][codacy]
|
|
13
|
+
[][codacy]
|
|
14
|
+
[][inchpages]
|
|
37
15
|
|
|
38
16
|
## Links
|
|
39
17
|
|
|
40
|
-
|
|
18
|
+
* [User documentation](https://dry-rb.org/gems/dry-monads)
|
|
19
|
+
* [API documentation](http://rubydoc.info/gems/dry-monads)
|
|
20
|
+
|
|
21
|
+
## Supported Ruby versions
|
|
41
22
|
|
|
42
|
-
|
|
23
|
+
This library officially supports the following Ruby versions:
|
|
43
24
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
prompt that will allow you to experiment.
|
|
25
|
+
* MRI `>= 2.6.0`
|
|
26
|
+
* ~~jruby~~ `>= 9.3` (we are waiting for [2.6 support](https://github.com/jruby/jruby/issues/6161))
|
|
47
27
|
|
|
48
|
-
##
|
|
28
|
+
## License
|
|
49
29
|
|
|
50
|
-
|
|
30
|
+
See `LICENSE` file.
|
data/dry-monads.gemspec
CHANGED
|
@@ -1,37 +1,39 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# this file is synced from dry-rb/template-gem project
|
|
4
|
+
|
|
5
|
+
lib = File.expand_path("lib", __dir__)
|
|
2
6
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
3
|
-
require
|
|
7
|
+
require "dry/monads/version"
|
|
4
8
|
|
|
5
9
|
Gem::Specification.new do |spec|
|
|
6
|
-
spec.name =
|
|
10
|
+
spec.name = "dry-monads"
|
|
11
|
+
spec.authors = ["Nikita Shilnikov"]
|
|
12
|
+
spec.email = ["fg@flashgordon.ru"]
|
|
13
|
+
spec.license = "MIT"
|
|
7
14
|
spec.version = Dry::Monads::VERSION.dup
|
|
8
|
-
spec.authors = ['Nikita Shilnikov']
|
|
9
|
-
spec.email = ['fg@flashgordon.ru']
|
|
10
|
-
spec.license = 'MIT'
|
|
11
15
|
|
|
12
|
-
spec.summary =
|
|
16
|
+
spec.summary = "Common monads for Ruby"
|
|
13
17
|
spec.description = spec.summary
|
|
14
|
-
spec.homepage =
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
spec.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
spec.
|
|
29
|
-
spec.
|
|
30
|
-
|
|
31
|
-
spec.
|
|
32
|
-
|
|
33
|
-
spec.add_development_dependency
|
|
34
|
-
spec.add_development_dependency
|
|
35
|
-
spec.add_development_dependency 'rspec'
|
|
36
|
-
spec.add_development_dependency 'dry-types', '>= 0.12'
|
|
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"
|
|
37
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/curry.rb
CHANGED
data/lib/dry/monads/do.rb
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "dry/monads/list"
|
|
4
|
+
require "dry/monads/do/mixin"
|
|
5
|
+
require "dry/monads/constants"
|
|
4
6
|
|
|
5
7
|
module Dry
|
|
6
8
|
module Monads
|
|
@@ -10,6 +12,14 @@ module Dry
|
|
|
10
12
|
module Do
|
|
11
13
|
extend Mixin
|
|
12
14
|
|
|
15
|
+
DELEGATE = ::RUBY_VERSION < "2.7" ? "*" : "..."
|
|
16
|
+
|
|
17
|
+
VISIBILITY_WORD = {
|
|
18
|
+
public: "",
|
|
19
|
+
private: "private ",
|
|
20
|
+
protected: "protected "
|
|
21
|
+
}.freeze
|
|
22
|
+
|
|
13
23
|
# @api private
|
|
14
24
|
class Halt < StandardError
|
|
15
25
|
# @api private
|
|
@@ -22,6 +32,25 @@ module Dry
|
|
|
22
32
|
end
|
|
23
33
|
end
|
|
24
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
|
+
|
|
25
54
|
class << self
|
|
26
55
|
# Generates a module that passes a block to methods
|
|
27
56
|
# that either unwraps a single-valued monadic value or halts
|
|
@@ -80,13 +109,11 @@ module Dry
|
|
|
80
109
|
# @param [Array<Symbol>] methods
|
|
81
110
|
# @return [Module]
|
|
82
111
|
def for(*methods)
|
|
83
|
-
mod = ::Module.new do
|
|
84
|
-
methods.each { |method_name| Do.wrap_method(self, method_name) }
|
|
85
|
-
end
|
|
86
|
-
|
|
87
112
|
::Module.new do
|
|
88
113
|
singleton_class.send(:define_method, :included) do |base|
|
|
114
|
+
mod = ::Module.new
|
|
89
115
|
base.prepend(mod)
|
|
116
|
+
base.extend(MethodTracker.new(methods, base, mod))
|
|
90
117
|
end
|
|
91
118
|
end
|
|
92
119
|
end
|
|
@@ -96,23 +123,34 @@ module Dry
|
|
|
96
123
|
super
|
|
97
124
|
|
|
98
125
|
# Actually mixes in Do::All
|
|
99
|
-
require
|
|
126
|
+
require "dry/monads/do/all"
|
|
100
127
|
base.include All
|
|
101
128
|
end
|
|
102
129
|
|
|
103
130
|
# @api private
|
|
104
|
-
def wrap_method(target,
|
|
131
|
+
def wrap_method(target, method, visibility)
|
|
105
132
|
target.module_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
|
106
|
-
def #{
|
|
107
|
-
if block_given?
|
|
108
|
-
super
|
|
109
|
-
else
|
|
110
|
-
Do.() { super { |*ms| Do.bind(ms) } }
|
|
111
|
-
end
|
|
112
|
-
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
|
|
113
140
|
RUBY
|
|
114
141
|
end
|
|
115
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
|
+
|
|
116
154
|
# @api private
|
|
117
155
|
def coerce_to_monad(monads)
|
|
118
156
|
return monads if monads.size != 1
|
|
@@ -131,7 +169,7 @@ module Dry
|
|
|
131
169
|
|
|
132
170
|
# @api private
|
|
133
171
|
def halt(result)
|
|
134
|
-
raise Halt.new(result),
|
|
172
|
+
raise Halt.new(result), "", []
|
|
135
173
|
end
|
|
136
174
|
end
|
|
137
175
|
end
|
data/lib/dry/monads/do/all.rb
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "dry/monads/do"
|
|
2
4
|
|
|
3
5
|
module Dry
|
|
4
6
|
module Monads
|
|
@@ -66,9 +68,10 @@ module Dry
|
|
|
66
68
|
tracker = self
|
|
67
69
|
|
|
68
70
|
module_eval do
|
|
71
|
+
private
|
|
72
|
+
|
|
69
73
|
define_method(:method_added) do |method|
|
|
70
74
|
super(method)
|
|
71
|
-
|
|
72
75
|
tracker.wrap_method(self, method)
|
|
73
76
|
end
|
|
74
77
|
|
|
@@ -91,20 +94,37 @@ module Dry
|
|
|
91
94
|
end
|
|
92
95
|
|
|
93
96
|
def wrap_method(target, method)
|
|
94
|
-
Do.
|
|
97
|
+
visibility = Do.method_visibility(target, method)
|
|
98
|
+
Do.wrap_method(wrappers[target], method, visibility)
|
|
95
99
|
end
|
|
96
100
|
end
|
|
97
101
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
102
|
+
class << self
|
|
103
|
+
# @api private
|
|
104
|
+
def included(base)
|
|
105
|
+
super
|
|
101
106
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
|
106
113
|
|
|
107
|
-
|
|
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
|
|
108
128
|
end
|
|
109
129
|
|
|
110
130
|
# @api private
|
|
@@ -114,16 +134,18 @@ module Dry
|
|
|
114
134
|
super
|
|
115
135
|
|
|
116
136
|
wrapper = ::Module.new
|
|
117
|
-
object.singleton_class
|
|
137
|
+
eigenclass = object.singleton_class
|
|
138
|
+
eigenclass.prepend(wrapper)
|
|
118
139
|
object.define_singleton_method(:singleton_method_added) do |method|
|
|
119
140
|
super(method)
|
|
120
141
|
|
|
121
142
|
next if method.equal?(:singleton_method_added)
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
Do.wrap_method(wrapper, m)
|
|
143
|
+
|
|
144
|
+
visibility = Do.method_visibility(eigenclass, method)
|
|
145
|
+
Do.wrap_method(wrapper, method, visibility)
|
|
126
146
|
end
|
|
147
|
+
|
|
148
|
+
All.wrap_defined_methods(eigenclass, wrapper)
|
|
127
149
|
end
|
|
128
150
|
end
|
|
129
151
|
|
|
@@ -131,7 +153,7 @@ module Dry
|
|
|
131
153
|
end
|
|
132
154
|
end
|
|
133
155
|
|
|
134
|
-
require
|
|
156
|
+
require "dry/monads/registry"
|
|
135
157
|
register_mixin(:do, Do::All)
|
|
136
158
|
end
|
|
137
159
|
end
|
data/lib/dry/monads/do/mixin.rb
CHANGED
data/lib/dry/monads/either.rb
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
require "dry/core/deprecations"
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Dry::Core::Deprecations.warn("Either monad was renamed to Result", tag: :"dry-monads")
|
|
6
|
+
|
|
7
|
+
require "dry/monads/result"
|
|
6
8
|
|
|
7
9
|
module Dry
|
|
8
10
|
module Monads
|
|
@@ -10,7 +12,7 @@ module Dry
|
|
|
10
12
|
deprecate_constant :Either
|
|
11
13
|
|
|
12
14
|
class Result
|
|
13
|
-
extend Dry::Core::Deprecations[:
|
|
15
|
+
extend ::Dry::Core::Deprecations[:"dry-monads"]
|
|
14
16
|
|
|
15
17
|
deprecate :to_either, :to_result
|
|
16
18
|
|
|
@@ -22,7 +24,7 @@ module Dry
|
|
|
22
24
|
|
|
23
25
|
module Mixin
|
|
24
26
|
module Constructors
|
|
25
|
-
extend Dry::Core::Deprecations[:
|
|
27
|
+
extend Dry::Core::Deprecations[:"dry-monads"]
|
|
26
28
|
|
|
27
29
|
Right = Success
|
|
28
30
|
Left = Failure
|
|
@@ -49,13 +51,13 @@ module Dry
|
|
|
49
51
|
|
|
50
52
|
class Try
|
|
51
53
|
class Value
|
|
52
|
-
extend Dry::Core::Deprecations[:
|
|
54
|
+
extend Dry::Core::Deprecations[:"dry-monads"]
|
|
53
55
|
|
|
54
56
|
deprecate :to_either, :to_result
|
|
55
57
|
end
|
|
56
58
|
|
|
57
59
|
class Error
|
|
58
|
-
extend Dry::Core::Deprecations[:
|
|
60
|
+
extend Dry::Core::Deprecations[:"dry-monads"]
|
|
59
61
|
|
|
60
62
|
deprecate :to_either, :to_result
|
|
61
63
|
end
|