dry-monads 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 06e9ae65089e5f79f92b2d1c67d463757dc960af7a7edbd92d527c0fb6cfd997
4
- data.tar.gz: 9d49d077c77edd1580bcc0cdd97fce2d527cabd9013b71611340b14ef6dae7d0
3
+ metadata.gz: 47e4a297e9fb56edfa596174c66abab2bee2587decfe47b474834ecbc2f13e41
4
+ data.tar.gz: 940384a98434a30026145d7caf12983440ac01fa63978885f4d72b4aafa1d76f
5
5
  SHA512:
6
- metadata.gz: 5720b87b50ce55e727f169e3bf62d4ad23aa0b6779b8086e326b79cf0242b93fc9f89f840f1a3d6718d2401461a19eea6e4f0679e91499816ccf295aee619d1d
7
- data.tar.gz: c95f43c4a51dd831d248cae4bc1afa8d226743e295081dfc4bf05a58c2e18aa146afd64dedb415b8189bbf3f2f54c0c0edb9033fb5a9367551f3fb6d88c37374
6
+ metadata.gz: 9076f344d5e8565b5acc9a3190d652a5f7f4217c04a0be8d4af7009c15779d84be0674f56a50a4bb473a679f608bf989df954d2c0408e67c7f3a1b4aa0bba86d
7
+ data.tar.gz: 99db2900d6fdd0af69d2e8b49303a3df85028fdf300b6998396e7bc6c6e60d1ca49bc684893fec4a5790e056d3af028e59f00251f960860eb65ce891291efa50
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  <!--- DO NOT EDIT THIS FILE - IT'S AUTOMATICALLY GENERATED VIA DEVTOOLS --->
2
2
 
3
+ ## 1.5.0 2022-10-16
4
+
5
+
6
+ ### Changed
7
+
8
+ - Use zeitwerk for auto-loading dry-monads classes (@flash-gordon)
9
+ - `Task#then` is deprecated in favor of `Task#bind` (@flash-gordon)
10
+ - Minimal Ruby version is now 2.7 (@flash-gordon)
11
+ - Either (old name of Result) was removed (@flash-gordon)
12
+
13
+ [Compare v1.4.0...v1.5.0](https://github.com/dry-rb/dry-monads/compare/v1.4.0...v1.5.0)
14
+
3
15
  ## 1.4.0 2021-07-20
4
16
 
5
17
 
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015-2021 dry-rb team
3
+ Copyright (c) 2015-2022 dry-rb team
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of
6
6
  this software and associated documentation files (the "Software"), to deal in
data/README.md CHANGED
@@ -8,10 +8,10 @@
8
8
  # dry-monads [![Join the chat at https://dry-rb.zulipchat.com](https://img.shields.io/badge/dry--rb-join%20chat-%23346b7a.svg)][chat]
9
9
 
10
10
  [![Gem Version](https://badge.fury.io/rb/dry-monads.svg)][gem]
11
- [![CI Status](https://github.com/dry-rb/dry-monads/workflows/CI/badge.svg)][actions]
11
+ [![CI Status](https://github.com/dry-rb/dry-monads/workflows/ci/badge.svg)][actions]
12
12
  [![Codacy Badge](https://api.codacy.com/project/badge/Grade/f2eed41bf7f04b38b0a7691c2cf6e73c)][codacy]
13
13
  [![Codacy Badge](https://api.codacy.com/project/badge/Coverage/f2eed41bf7f04b38b0a7691c2cf6e73c)][codacy]
14
- [![Inline docs](http://inch-ci.org/github/dry-rb/dry-monads.svg?branch=master)][inchpages]
14
+ [![Inline docs](http://inch-ci.org/github/dry-rb/dry-monads.svg?branch=main)][inchpages]
15
15
 
16
16
  ## Links
17
17
 
@@ -22,8 +22,8 @@
22
22
 
23
23
  This library officially supports the following Ruby versions:
24
24
 
25
- * MRI `>= 2.6.0`
26
- * ~~jruby~~ `>= 9.3` (we are waiting for [2.6 support](https://github.com/jruby/jruby/issues/6161))
25
+ * MRI `>= 2.7.0`
26
+ * jruby `>= 9.3` (postponed until 2.7 is supported)
27
27
 
28
28
  ## License
29
29
 
data/dry-monads.gemspec CHANGED
@@ -22,15 +22,16 @@ Gem::Specification.new do |spec|
22
22
  spec.require_paths = ["lib"]
23
23
 
24
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"
25
+ spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-monads/blob/main/CHANGELOG.md"
26
26
  spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-monads"
27
27
  spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-monads/issues"
28
28
 
29
- spec.required_ruby_version = ">= 2.6.0"
29
+ spec.required_ruby_version = ">= 2.7.0"
30
30
 
31
31
  # to update dependencies edit project.yml
32
32
  spec.add_runtime_dependency "concurrent-ruby", "~> 1.0"
33
- spec.add_runtime_dependency "dry-core", "~> 0.7"
33
+ spec.add_runtime_dependency "dry-core", "~> 0.9", ">= 0.9"
34
+ spec.add_runtime_dependency "zeitwerk", "~> 2.6"
34
35
 
35
36
  spec.add_development_dependency "bundler"
36
37
  spec.add_development_dependency "dry-types", ">= 0.1.2"
@@ -1,11 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "dry/monads"
4
- require "dry/monads/registry"
5
4
 
6
5
  module Dry
7
6
  module Monads
8
- known_monads.each { |m| load_monad(m) }
7
+ known_monads.each { load_monad(_1) }
9
8
  extend(*constructors)
10
9
  end
11
10
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "dry/core/constants"
4
-
5
3
  module Dry
6
4
  module Monads
7
5
  # @private
@@ -7,8 +7,8 @@ module Dry
7
7
  # @private
8
8
  def self.call(value)
9
9
  func = value.is_a?(Proc) ? value : value.method(:call)
10
- seq_args = func.parameters.count { |type, _| type == :req || type == :opt }
11
- seq_args += 1 if func.parameters.any? { |type, _| type == :keyreq }
10
+ seq_args = func.parameters.count { |type, _| type.eql?(:req) || type.eql?(:opt) }
11
+ seq_args += 1 if func.parameters.any? { |type, _| type.eql?(:keyreq) }
12
12
 
13
13
  if seq_args > 1
14
14
  func.curry
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "dry/monads/do"
4
-
5
3
  module Dry
6
4
  module Monads
7
5
  module Do
@@ -104,7 +102,7 @@ module Dry
104
102
  def included(base)
105
103
  super
106
104
 
107
- wrappers = ::Hash.new { |h, k| h[k] = ::Module.new }
105
+ wrappers = ::Hash.new { _1[_2] = ::Module.new }
108
106
  tracker = MethodTracker.new(wrappers)
109
107
  base.extend(tracker)
110
108
  base.extend(InstanceMixin) unless base.is_a?(::Class)
data/lib/dry/monads/do.rb CHANGED
@@ -1,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "dry/monads/list"
4
- require "dry/monads/do/mixin"
5
- require "dry/monads/constants"
6
-
7
3
  module Dry
8
4
  module Monads
9
5
  # An implementation of do-notation.
@@ -12,8 +8,6 @@ module Dry
12
8
  module Do
13
9
  extend Mixin
14
10
 
15
- DELEGATE = ::RUBY_VERSION < "2.7" ? "*" : "..."
16
-
17
11
  VISIBILITY_WORD = {
18
12
  public: "",
19
13
  private: "private ",
@@ -110,7 +104,7 @@ module Dry
110
104
  # @return [Module]
111
105
  def for(*methods)
112
106
  ::Module.new do
113
- singleton_class.send(:define_method, :included) do |base|
107
+ singleton_class.define_method(:included) do |base|
114
108
  mod = ::Module.new
115
109
  base.prepend(mod)
116
110
  base.extend(MethodTracker.new(methods, base, mod))
@@ -130,13 +124,13 @@ module Dry
130
124
  # @api private
131
125
  def wrap_method(target, method, visibility)
132
126
  target.module_eval(<<-RUBY, __FILE__, __LINE__ + 1)
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
127
+ #{VISIBILITY_WORD[visibility]} def #{method}(...) # private def create_acccount(...)
128
+ if block_given? # if block_given?
129
+ super # super
130
+ else # else
131
+ Do.() { super { |*ms| Do.bind(ms) } } # Do.() { super { |*ms| Do.bind(ms) } }
132
+ end # end
133
+ end # end
140
134
  RUBY
141
135
  end
142
136
 
@@ -3,7 +3,7 @@
3
3
  module Dry
4
4
  module Monads
5
5
  # An unsuccessful result of extracting a value from a monad.
6
- class UnwrapError < StandardError
6
+ class UnwrapError < ::StandardError
7
7
  attr_reader :receiver
8
8
 
9
9
  def initialize(receiver)
@@ -13,14 +13,14 @@ module Dry
13
13
  end
14
14
 
15
15
  # An error thrown on returning a Failure of unknown type.
16
- class InvalidFailureTypeError < StandardError
16
+ class InvalidFailureTypeError < ::StandardError
17
17
  def initialize(failure)
18
18
  super("Cannot create Failure from #{failure.inspect}, it doesn't meet the constraints")
19
19
  end
20
20
  end
21
21
 
22
22
  # Improper use of None
23
- class ConstructorNotAppliedError < NoMethodError
23
+ class ConstructorNotAppliedError < ::NoMethodError
24
24
  def initialize(method_name, constructor_name)
25
25
  super(
26
26
  "For calling .#{method_name} on #{constructor_name}() build a value "\
@@ -2,9 +2,6 @@
2
2
 
3
3
  require "concurrent/promise"
4
4
 
5
- require "dry/core/deprecations"
6
- require "dry/monads/task"
7
-
8
5
  module Dry
9
6
  module Monads
10
7
  # Lazy is a twin of Task which is always executed on the current thread.
@@ -1,15 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "dry/core/equalizer"
4
-
5
- require "dry/monads/maybe"
6
- require "dry/monads/task"
7
- require "dry/monads/result"
8
- require "dry/monads/try"
9
- require "dry/monads/validated"
10
- require "dry/monads/transformer"
11
- require "dry/monads/curry"
12
-
13
3
  module Dry
14
4
  module Monads
15
5
  # The List monad.
@@ -110,10 +100,10 @@ module Dry
110
100
  # @return [List]
111
101
  def bind(*args)
112
102
  if block_given?
113
- List.coerce(value.map { |v| yield(v, *args) }.reduce([], &:+))
103
+ List.coerce(value.map { yield(_1, *args) }.reduce([], &:+))
114
104
  else
115
105
  obj, *rest = args
116
- List.coerce(value.map { |v| obj.(v, *rest) }.reduce([], &:+))
106
+ List.coerce(value.map { obj.(_1, *rest) }.reduce([], &:+))
117
107
  end
118
108
  end
119
109
 
@@ -128,10 +118,10 @@ module Dry
128
118
  # @return [List]
129
119
  def fmap(*args)
130
120
  if block_given?
131
- List.new(value.map { |v| yield(v, *args) })
121
+ List.new(value.map { yield(_1, *args) })
132
122
  else
133
123
  obj, *rest = args
134
- List.new(value.map { |v| obj.(v, *rest) })
124
+ List.new(value.map { obj.(_1, *rest) })
135
125
  end
136
126
  end
137
127
 
@@ -270,7 +260,7 @@ module Dry
270
260
  self.class.warn(
271
261
  "Automatic monad inference is deprecated, pass a type explicitly "\
272
262
  "or use a predefined constant, e.g. List::Result\n"\
273
- "#{caller.find { |l| l !~ %r{(lib/dry/monads)|(gems)} }}"
263
+ "#{caller.find { _1 !~ %r{(lib/dry/monads)|(gems)} }}"
274
264
  )
275
265
  self.class.new(value, value[0].monad)
276
266
  end
@@ -317,7 +307,7 @@ module Dry
317
307
  # @return [List]
318
308
  def apply(list = Undefined, &block)
319
309
  v = Undefined.default(list, &block)
320
- fmap(Curry).bind { |f| v.fmap { |x| f.(x) } }
310
+ fmap(Curry).bind { |f| v.fmap { f.(_1) } }
321
311
  end
322
312
 
323
313
  # Returns the List monad.
@@ -362,7 +352,7 @@ module Dry
362
352
  List.new(collected)
363
353
  else
364
354
  Enumerator.new do |g|
365
- value.each { |x| g << x.value! if x.some? }
355
+ value.each { g << _1.value! if _1.some? }
366
356
  end
367
357
  end
368
358
  end
@@ -1,14 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "dry/core/equalizer"
4
- require "dry/core/deprecations"
5
- require "dry/core/class_attributes"
6
-
7
- require "dry/monads/right_biased"
8
- require "dry/monads/transformer"
9
- require "dry/monads/unit"
10
- require "dry/monads/constants"
11
-
12
3
  module Dry
13
4
  module Monads
14
5
  # Represents a value which can exist or not, i.e. it could be nil.
@@ -127,8 +118,8 @@ module Dry
127
118
  # @param args [Array<Object>] arguments will be transparently passed through to #bind
128
119
  # @return [Maybe::Some, Maybe::None] Wrapped result, i.e. nil will be mapped to None,
129
120
  # other values will be wrapped with Some
130
- def fmap(*args, &block)
131
- next_value = bind(*args, &block)
121
+ def fmap(...)
122
+ next_value = bind(...)
132
123
 
133
124
  if next_value.nil?
134
125
  if self.class.warn_on_implicit_nil_coercion
@@ -140,7 +131,7 @@ module Dry
140
131
  "You can opt out of these warnings with\n"\
141
132
  "Dry::Monads::Maybe.warn_on_implicit_nil_coercion false",
142
133
  uplevel: 0,
143
- tag: :'dry-monads'
134
+ tag: :"dry-monads"
144
135
  )
145
136
  end
146
137
  Monads.None()
@@ -160,8 +151,8 @@ module Dry
160
151
  # @param args [Array<Object>] arguments will be transparently passed through to #bind
161
152
  # @return [Maybe::Some, Maybe::None] Wrapped result, i.e. nil will be mapped to None,
162
153
  # other values will be wrapped with Some
163
- def maybe(*args, &block)
164
- Maybe.coerce(bind(*args, &block))
154
+ def maybe(...)
155
+ Maybe.coerce(bind(...))
165
156
  end
166
157
 
167
158
  # Accepts a block and runs it against the wrapped value.
@@ -201,7 +192,7 @@ module Dry
201
192
  include RightBiased::Left
202
193
 
203
194
  @instance = new.freeze
204
- singleton_class.send(:attr_reader, :instance)
195
+ singleton_class.attr_reader(:instance)
205
196
 
206
197
  # @api private
207
198
  def self.method_missing(m, *) # rubocop:disable Style/MissingRespondToMissing
@@ -255,8 +246,8 @@ module Dry
255
246
  # @param args [Array<Object>] arguments will be passed to the underlying `#or` call
256
247
  # @return [Maybe::Some, Maybe::None] Lifted `#or` result, i.e. nil will be mapped to None,
257
248
  # other values will be wrapped with Some
258
- def or_fmap(*args, &block)
259
- Maybe.coerce(self.or(*args, &block))
249
+ def or_fmap(...)
250
+ Maybe.coerce(self.or(...))
260
251
  end
261
252
 
262
253
  # @return [String]
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "concurrent/map"
4
-
5
3
  module Dry
6
4
  # Common, idiomatic monads for Ruby
7
5
  #
@@ -9,20 +7,20 @@ module Dry
9
7
  module Monads
10
8
  @registry = {}
11
9
  @constructors = nil
12
- @paths = {
13
- do: "dry/monads/do/all",
14
- lazy: "dry/monads/lazy",
15
- list: "dry/monads/list",
16
- maybe: "dry/monads/maybe",
17
- task: "dry/monads/task",
18
- try: "dry/monads/try",
19
- validated: "dry/monads/validated",
10
+ @constants = {
11
+ do: "Do::All",
12
+ lazy: "Lazy",
13
+ list: "List",
14
+ maybe: "Maybe",
15
+ task: "Task",
16
+ try: "Try",
17
+ validated: "Validated",
20
18
  result: [
21
- "dry/monads/result",
22
- "dry/monads/result/fixed"
19
+ "Result",
20
+ "Result::Fixed"
23
21
  ]
24
22
  }.freeze
25
- @mixins = Concurrent::Map.new
23
+ @mixins = ::Concurrent::Map.new
26
24
 
27
25
  class << self
28
26
  private
@@ -46,27 +44,29 @@ module Dry
46
44
 
47
45
  # @private
48
46
  def known_monads
49
- @paths.keys
47
+ @constants.keys
50
48
  end
51
49
 
52
50
  # @private
53
51
  def load_monad(name)
54
- path = @paths.fetch(name) {
55
- raise ArgumentError, "#{name.inspect} is not a known monad"
52
+ constants = @constants.fetch(name) {
53
+ raise ::ArgumentError, "#{name.inspect} is not a known monad"
56
54
  }
57
- Array(path).each { |p| require p }
55
+ Array(constants).each do |const_name|
56
+ const_name.split("::").reduce(Monads) { |mod, const| mod.const_get(const) }
57
+ end
58
58
  end
59
59
 
60
60
  # @private
61
61
  def constructors
62
- @constructors ||= registry.values.map { |m|
62
+ @constructors ||= registry.values.filter_map { |m|
63
63
  m::Constructors if m.const_defined?(:Constructors)
64
- }.compact
64
+ }
65
65
  end
66
66
 
67
67
  # @private
68
68
  def all_loaded?
69
- registry.size == @paths.size
69
+ registry.size.eql?(@constants.size)
70
70
  end
71
71
  end
72
72
  end
@@ -20,10 +20,8 @@ module Dry
20
20
  if error === value
21
21
  Failure.new(value, RightBiased::Left.trace_caller)
22
22
  else
23
- # rubocop:disable Style/RaiseArgs
24
23
  # per https://github.com/dry-rb/dry-monads/pull/142
25
24
  raise InvalidFailureTypeError.new(value)
26
- # rubocop:enable Style/RaiseArgs
27
25
  end
28
26
  end
29
27
 
@@ -1,13 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "dry/core/equalizer"
4
-
5
- require "dry/monads/constants"
6
- require "dry/monads/right_biased"
7
- require "dry/monads/transformer"
8
- require "dry/monads/conversion_stubs"
9
- require "dry/monads/unit"
10
-
11
3
  module Dry
12
4
  module Monads
13
5
  # Represents an operation which either succeeded or failed.
@@ -116,8 +108,8 @@ module Dry
116
108
  #
117
109
  # @param args [Array<Object>] arguments will be transparently passed through to #bind
118
110
  # @return [Result::Success]
119
- def fmap(*args, &block)
120
- Success.new(bind(*args, &block))
111
+ def fmap(...)
112
+ Success.new(bind(...))
121
113
  end
122
114
 
123
115
  # Returns result of applying first function to the internal value.
@@ -164,7 +156,7 @@ module Dry
164
156
  include RightBiased::Left
165
157
  include Dry::Equalizer(:failure)
166
158
 
167
- singleton_class.send(:alias_method, :call, :new)
159
+ singleton_class.alias_method(:call, :new)
168
160
 
169
161
  # Shortcut for Failure([...])
170
162
  #
@@ -251,8 +243,8 @@ module Dry
251
243
  #
252
244
  # @param args [Array<Object>] arguments will be passed to the underlying `#or` call
253
245
  # @return [Result::Success] Wrapped value
254
- def or_fmap(*args, &block)
255
- Success.new(self.or(*args, &block))
246
+ def or_fmap(...)
247
+ Success.new(self.or(...))
256
248
  end
257
249
 
258
250
  # @return [String]
@@ -1,10 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "dry/monads/constants"
4
- require "dry/monads/unit"
5
- require "dry/monads/curry"
6
- require "dry/monads/errors"
7
-
8
3
  module Dry
9
4
  module Monads
10
5
  # A common module for right-biased monads, such as Result/Either, Maybe, and Try.
@@ -12,7 +7,7 @@ module Dry
12
7
  # Right part
13
8
  #
14
9
  # @api public
15
- module Right # rubocop:disable Metrics/ModuleLength
10
+ module Right
16
11
  # @private
17
12
  def self.included(m)
18
13
  super
@@ -20,7 +15,7 @@ module Dry
20
15
  def m.to_proc
21
16
  @to_proc ||= method(:new).to_proc
22
17
  end
23
- m.singleton_class.send(:alias_method, :call, :new)
18
+ m.singleton_class.alias_method(:call, :new)
24
19
  end
25
20
 
26
21
  # Unwraps the underlying value
@@ -70,8 +65,8 @@ module Dry
70
65
  #
71
66
  # @param [Array<Object>] args arguments will be transparently passed through to #bind
72
67
  # @return [RightBiased::Right]
73
- def tee(*args, &block)
74
- bind(*args, &block).bind { self }
68
+ def tee(...)
69
+ bind(...).bind { self }
75
70
  end
76
71
 
77
72
  # Abstract method for lifting a block over the monad type.
@@ -133,7 +128,7 @@ module Dry
133
128
  raise TypeError, "Cannot apply #{val.inspect} to #{@value.inspect}"
134
129
  end
135
130
 
136
- Undefined.default(val, &block).fmap { |unwrapped| curry.(unwrapped) }
131
+ Undefined.default(val, &block).fmap { curry.(_1) }
137
132
  end
138
133
 
139
134
  # @param other [Object]
@@ -236,19 +231,12 @@ module Dry
236
231
 
237
232
  private
238
233
 
239
- if RUBY_VERSION >= "2.7"
240
- # @api private
241
- def destructure(value)
242
- if value.is_a?(::Hash)
243
- [EMPTY_ARRAY, value]
244
- else
245
- [[value], EMPTY_HASH]
246
- end
247
- end
248
- else
249
- # @api private
250
- def destructure(*args, **kwargs)
251
- [args, kwargs]
234
+ # @api private
235
+ def destructure(value)
236
+ if value.is_a?(::Hash)
237
+ [EMPTY_ARRAY, value]
238
+ else
239
+ [[value], EMPTY_HASH]
252
240
  end
253
241
  end
254
242
 
@@ -2,10 +2,6 @@
2
2
 
3
3
  require "concurrent/promise"
4
4
 
5
- require "dry/monads/unit"
6
- require "dry/monads/curry"
7
- require "dry/monads/conversion_stubs"
8
-
9
5
  module Dry
10
6
  module Monads
11
7
  # The Task monad represents an async computation. The implementation
@@ -15,7 +11,7 @@ module Dry
15
11
  # @api public
16
12
  class Task
17
13
  # @api private
18
- class Promise < Concurrent::Promise
14
+ class Promise < ::Concurrent::Promise
19
15
  public :on_fulfill, :on_reject
20
16
  end
21
17
  private_constant :Promise
@@ -83,6 +79,7 @@ module Dry
83
79
  end
84
80
 
85
81
  include ConversionStubs[:to_maybe, :to_result]
82
+ extend ::Dry::Core::Deprecations[:"dry-monads"]
86
83
 
87
84
  # @api private
88
85
  attr_reader :promise
@@ -124,9 +121,9 @@ module Dry
124
121
  # and returns another task
125
122
  # @return [Task]
126
123
  def bind(&block)
127
- self.class.new(promise.flat_map { |value| block.(value).promise })
124
+ self.class.new(promise.flat_map { block.(_1).promise })
128
125
  end
129
- alias_method :then, :bind
126
+ deprecate :then, :bind
130
127
 
131
128
  # @return [String]
132
129
  def to_s
@@ -168,12 +165,12 @@ module Dry
168
165
  promise.on_error do |v|
169
166
  inner = block.(v).promise
170
167
  inner.execute
171
- inner.on_success { |r| child.on_fulfill(r) }
172
- inner.on_error { |e| child.on_reject(e) }
168
+ inner.on_success { child.on_fulfill(_1) }
169
+ inner.on_error { child.on_reject(_1) }
173
170
  rescue StandardError => e
174
171
  child.on_reject(e)
175
172
  end
176
- promise.on_success { |v| child.on_fulfill(v) }
173
+ promise.on_success { child.on_fulfill(_1) }
177
174
 
178
175
  self.class.new(child)
179
176
  end
@@ -238,7 +235,7 @@ module Dry
238
235
  # @return [Task]
239
236
  def apply(val = Undefined, &block)
240
237
  arg = Undefined.default(val, &block)
241
- bind { |f| arg.fmap { |v| curry(f).(v) } }
238
+ bind { |f| arg.fmap { curry(f).(_1) } }
242
239
  end
243
240
 
244
241
  # Maps a successful result to Unit, effectively discards it
@@ -267,8 +264,8 @@ module Dry
267
264
  # @api private
268
265
  def compare_promises(x, y)
269
266
  x.equal?(y) ||
270
- x.fulfilled? && y.fulfilled? && x.value == y.value ||
271
- x.rejected? && y.rejected? && x.reason == y.reason
267
+ (x.fulfilled? && y.fulfilled? && x.value == y.value) ||
268
+ (x.rejected? && y.rejected? && x.reason == y.reason)
272
269
  end
273
270
 
274
271
  # Task constructors.
@@ -3,8 +3,6 @@
3
3
  # rubocop:disable Naming/ConstantName
4
4
  # rubocop:disable Style/MutableConstant
5
5
 
6
- require "dry/monads/validated"
7
-
8
6
  module Dry
9
7
  module Monads
10
8
  to_list = List::Validated.method(:pure)
@@ -1,11 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "dry/core/equalizer"
4
- require "dry/core/deprecations"
5
-
6
- require "dry/monads/right_biased"
7
- require "dry/monads/conversion_stubs"
8
-
9
3
  module Dry
10
4
  module Monads
11
5
  # Represents a value which can be either success or a failure (an exception).
@@ -135,7 +129,7 @@ module Dry
135
129
  # object and the rest of args will be passed
136
130
  # to this object along with the internal value
137
131
  # @return [Object, Try::Error]
138
- def bind(*args)
132
+ def bind(...)
139
133
  super
140
134
  rescue *catchable => e
141
135
  Error.new(e)
@@ -153,8 +147,8 @@ module Dry
153
147
  # @param args [Array<Object>] extra arguments for the block, arguments are being processes
154
148
  # just as in #bind
155
149
  # @return [Try::Value, Try::Error]
156
- def fmap(*args, &block)
157
- Value.new(catchable, bind_call(*args, &block))
150
+ def fmap(...)
151
+ Value.new(catchable, bind_call(...))
158
152
  rescue *catchable => e
159
153
  Error.new(e)
160
154
  end
@@ -186,7 +180,7 @@ module Dry
186
180
  include Dry::Equalizer(:exception)
187
181
  include RightBiased::Left
188
182
 
189
- singleton_class.send(:alias_method, :call, :new)
183
+ singleton_class.alias_method(:call, :new)
190
184
 
191
185
  # @param exception [Exception]
192
186
  def initialize(exception)
@@ -238,7 +232,7 @@ module Dry
238
232
  classes = errors
239
233
  end
240
234
 
241
- if classes.any? { |c| c === exception }
235
+ if classes.any? { _1 === exception }
242
236
  Value.new([exception.class], yield(exception))
243
237
  else
244
238
  self
@@ -18,7 +18,7 @@ module Dry
18
18
  # Maybe(Unit)
19
19
  # => Some(Unit)
20
20
  #
21
- Unit = Object.new.tap do |unit|
21
+ Unit = ::Object.new.tap do |unit|
22
22
  def unit.to_s
23
23
  "Unit"
24
24
  end
@@ -30,6 +30,8 @@ module Dry
30
30
  def unit.deconstruct
31
31
  EMPTY_ARRAY
32
32
  end
33
+
34
+ unit.freeze
33
35
  end
34
36
  end
35
37
  end
@@ -1,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "dry/monads/conversion_stubs"
4
- require "dry/monads/constants"
5
- require "dry/monads/right_biased"
6
-
7
3
  module Dry
8
4
  module Monads
9
5
  # Validated is similar to Result and represents an outcome of a validation.
@@ -175,7 +171,7 @@ module Dry
175
171
  def apply(val = Undefined, &block)
176
172
  Undefined
177
173
  .default(val, &block)
178
- .alt_map { |v| @error + v }
174
+ .alt_map { @error + _1 }
179
175
  .fmap { return self }
180
176
  end
181
177
 
@@ -3,6 +3,6 @@
3
3
  module Dry
4
4
  module Monads
5
5
  # Gem version
6
- VERSION = "1.4.0"
6
+ VERSION = "1.5.0"
7
7
  end
8
8
  end
data/lib/dry/monads.rb CHANGED
@@ -1,6 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "dry/core/constants"
3
+ require "concurrent/map"
4
+ require "zeitwerk"
5
+ require "dry/core"
6
+ require "dry/monads/constants"
7
+ require "dry/monads/errors"
4
8
  require "dry/monads/registry"
5
9
 
6
10
  module Dry
@@ -8,6 +12,21 @@ module Dry
8
12
  #
9
13
  # @api public
10
14
  module Monads
15
+ # @api private
16
+ def self.loader
17
+ @loader ||= Zeitwerk::Loader.new.tap do |loader|
18
+ root = File.expand_path("..", __dir__)
19
+ loader.tag = "dry-monads"
20
+ loader.inflector = Zeitwerk::GemInflector.new("#{root}/dry-monads.rb")
21
+ loader.push_dir(root)
22
+ loader.ignore(
23
+ "#{root}/dry-monads.rb",
24
+ "#{root}/dry/monads/{all,constants,errors,registry,version}.rb",
25
+ "#{root}/json/**/*.rb"
26
+ )
27
+ end
28
+ end
29
+
11
30
  # @private
12
31
  def self.included(base)
13
32
  if all_loaded?
@@ -49,10 +68,12 @@ module Dry
49
68
  def self.[](*monads)
50
69
  monads.sort!
51
70
  @mixins.fetch_or_store(monads.hash) do
52
- monads.each { |m| load_monad(m) }
53
- mixins = monads.map { |m| registry.fetch(m) }
71
+ monads.each { load_monad(_1) }
72
+ mixins = monads.map { registry.fetch(_1) }
54
73
  ::Module.new { include(*mixins) }.freeze
55
74
  end
56
75
  end
76
+
77
+ loader.setup
57
78
  end
58
79
  end
@@ -26,8 +26,8 @@ module Dry
26
26
 
27
27
  # Stores class name (Dry::Monads::Maybe::Some or Dry::Monads::Maybe::None)
28
28
  # with the monad value as JSON string
29
- def to_json(*args)
30
- as_json.to_json(*args)
29
+ def to_json(...)
30
+ as_json.to_json(...)
31
31
  end
32
32
  end
33
33
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-monads
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nikita Shilnikov
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-20 00:00:00.000000000 Z
11
+ date: 2022-10-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -30,14 +30,34 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0.7'
33
+ version: '0.9'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: '0.9'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '0.9'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0.9'
47
+ - !ruby/object:Gem::Dependency
48
+ name: zeitwerk
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '2.6'
34
54
  type: :runtime
35
55
  prerelease: false
36
56
  version_requirements: !ruby/object:Gem::Requirement
37
57
  requirements:
38
58
  - - "~>"
39
59
  - !ruby/object:Gem::Version
40
- version: '0.7'
60
+ version: '2.6'
41
61
  - !ruby/object:Gem::Dependency
42
62
  name: bundler
43
63
  requirement: !ruby/object:Gem::Requirement
@@ -114,7 +134,6 @@ files:
114
134
  - lib/dry/monads/do.rb
115
135
  - lib/dry/monads/do/all.rb
116
136
  - lib/dry/monads/do/mixin.rb
117
- - lib/dry/monads/either.rb
118
137
  - lib/dry/monads/errors.rb
119
138
  - lib/dry/monads/lazy.rb
120
139
  - lib/dry/monads/list.rb
@@ -136,10 +155,10 @@ licenses:
136
155
  - MIT
137
156
  metadata:
138
157
  allowed_push_host: https://rubygems.org
139
- changelog_uri: https://github.com/dry-rb/dry-monads/blob/master/CHANGELOG.md
158
+ changelog_uri: https://github.com/dry-rb/dry-monads/blob/main/CHANGELOG.md
140
159
  source_code_uri: https://github.com/dry-rb/dry-monads
141
160
  bug_tracker_uri: https://github.com/dry-rb/dry-monads/issues
142
- post_install_message:
161
+ post_install_message:
143
162
  rdoc_options: []
144
163
  require_paths:
145
164
  - lib
@@ -147,15 +166,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
147
166
  requirements:
148
167
  - - ">="
149
168
  - !ruby/object:Gem::Version
150
- version: 2.6.0
169
+ version: 2.7.0
151
170
  required_rubygems_version: !ruby/object:Gem::Requirement
152
171
  requirements:
153
172
  - - ">="
154
173
  - !ruby/object:Gem::Version
155
174
  version: '0'
156
175
  requirements: []
157
- rubygems_version: 3.2.22
158
- signing_key:
176
+ rubygems_version: 3.1.6
177
+ signing_key:
159
178
  specification_version: 4
160
179
  summary: Common monads for Ruby
161
180
  test_files: []
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "dry/core/deprecations"
4
-
5
- Dry::Core::Deprecations.warn("Either monad was renamed to Result", tag: :"dry-monads")
6
-
7
- require "dry/monads/result"
8
-
9
- module Dry
10
- module Monads
11
- Either = Result
12
- deprecate_constant :Either
13
-
14
- class Result
15
- extend ::Dry::Core::Deprecations[:"dry-monads"]
16
-
17
- deprecate :to_either, :to_result
18
-
19
- Right = Success
20
- Left = Failure
21
-
22
- deprecate_constant :Right
23
- deprecate_constant :Left
24
-
25
- module Mixin
26
- module Constructors
27
- extend Dry::Core::Deprecations[:"dry-monads"]
28
-
29
- Right = Success
30
- Left = Failure
31
- deprecate_constant :Right
32
- deprecate_constant :Left
33
-
34
- deprecate :Right, :Success
35
- deprecate :Left, :Failure
36
- end
37
- end
38
-
39
- class Success
40
- deprecate :left?, :failure?
41
- deprecate :right?, :success?
42
- end
43
-
44
- class Failure
45
- deprecate :left?, :failure?
46
- deprecate :right?, :success?
47
-
48
- deprecate :left, :failure
49
- end
50
- end
51
-
52
- class Try
53
- class Value
54
- extend Dry::Core::Deprecations[:"dry-monads"]
55
-
56
- deprecate :to_either, :to_result
57
- end
58
-
59
- class Error
60
- extend Dry::Core::Deprecations[:"dry-monads"]
61
-
62
- deprecate :to_either, :to_result
63
- end
64
- end
65
- end
66
- end