dry-effects 0.1.5 → 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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +34 -0
  3. data/LICENSE +1 -1
  4. data/README.md +5 -4
  5. data/dry-effects.gemspec +15 -15
  6. data/lib/dry/effects/all.rb +3 -3
  7. data/lib/dry/effects/container.rb +1 -1
  8. data/lib/dry/effects/effect.rb +1 -2
  9. data/lib/dry/effects/effects/async.rb +4 -2
  10. data/lib/dry/effects/effects/cache.rb +13 -9
  11. data/lib/dry/effects/effects/cmp.rb +3 -1
  12. data/lib/dry/effects/effects/current_time.rb +4 -2
  13. data/lib/dry/effects/effects/defer.rb +3 -1
  14. data/lib/dry/effects/effects/env.rb +3 -1
  15. data/lib/dry/effects/effects/fork.rb +3 -1
  16. data/lib/dry/effects/effects/implicit.rb +3 -1
  17. data/lib/dry/effects/effects/interrupt.rb +3 -1
  18. data/lib/dry/effects/effects/lock.rb +3 -1
  19. data/lib/dry/effects/effects/parallel.rb +4 -2
  20. data/lib/dry/effects/effects/random.rb +3 -1
  21. data/lib/dry/effects/effects/reader.rb +1 -1
  22. data/lib/dry/effects/effects/resolve.rb +24 -4
  23. data/lib/dry/effects/effects/retry.rb +4 -2
  24. data/lib/dry/effects/effects/state.rb +4 -2
  25. data/lib/dry/effects/effects/timeout.rb +3 -1
  26. data/lib/dry/effects/effects/timestamp.rb +3 -1
  27. data/lib/dry/effects/errors.rb +4 -4
  28. data/lib/dry/effects/extensions/active_support/tagged_logging.rb +1 -1
  29. data/lib/dry/effects/extensions/auto_inject.rb +5 -5
  30. data/lib/dry/effects/extensions/system.rb +9 -8
  31. data/lib/dry/effects/extensions.rb +4 -6
  32. data/lib/dry/effects/frame.rb +23 -9
  33. data/lib/dry/effects/halt.rb +2 -3
  34. data/lib/dry/effects/handler.rb +2 -10
  35. data/lib/dry/effects/inflector.rb +1 -1
  36. data/lib/dry/effects/initializer.rb +17 -17
  37. data/lib/dry/effects/instructions/execute.rb +2 -1
  38. data/lib/dry/effects/instructions/raise.rb +2 -1
  39. data/lib/dry/effects/provider/class_interface.rb +1 -2
  40. data/lib/dry/effects/provider.rb +2 -2
  41. data/lib/dry/effects/providers/async.rb +2 -2
  42. data/lib/dry/effects/providers/cache.rb +2 -2
  43. data/lib/dry/effects/providers/cmp.rb +1 -1
  44. data/lib/dry/effects/providers/current_time/time_generators.rb +1 -1
  45. data/lib/dry/effects/providers/current_time.rb +5 -5
  46. data/lib/dry/effects/providers/defer.rb +7 -7
  47. data/lib/dry/effects/providers/env.rb +3 -3
  48. data/lib/dry/effects/providers/fork.rb +2 -2
  49. data/lib/dry/effects/providers/implicit.rb +1 -1
  50. data/lib/dry/effects/providers/interrupt.rb +3 -3
  51. data/lib/dry/effects/providers/lock.rb +5 -8
  52. data/lib/dry/effects/providers/parallel.rb +3 -3
  53. data/lib/dry/effects/providers/random.rb +5 -4
  54. data/lib/dry/effects/providers/reader.rb +1 -1
  55. data/lib/dry/effects/providers/resolve.rb +8 -7
  56. data/lib/dry/effects/providers/retry.rb +5 -7
  57. data/lib/dry/effects/providers/state.rb +2 -2
  58. data/lib/dry/effects/providers/timeout.rb +2 -2
  59. data/lib/dry/effects/providers/timestamp.rb +2 -2
  60. data/lib/dry/effects/stack.rb +7 -7
  61. data/lib/dry/effects/version.rb +1 -1
  62. data/lib/dry/effects.rb +9 -9
  63. metadata +9 -29
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/system/container'
3
+ require "dry/system"
4
4
 
5
5
  Dry::Effects.load_extensions(:auto_inject)
6
6
 
@@ -8,17 +8,18 @@ module Dry
8
8
  module Effects
9
9
  module System
10
10
  class AutoRegistrar < ::Dry::System::AutoRegistrar
11
- def call(dir)
12
- super do |config|
13
- config.memoize = true
14
- config.instance { |c| c.instance.freeze }
15
- yield(config) if block_given?
11
+ # Always memoize and freeze registered components
12
+ def call(component_dir)
13
+ component_dir.each_component do |component|
14
+ next unless register_component?(component)
15
+
16
+ container.register(component.key, memoize: true) { component.instance.freeze }
16
17
  end
17
18
  end
18
19
  end
19
20
 
20
21
  class Container < ::Dry::System::Container
21
- setting :auto_registrar, AutoRegistrar
22
+ setting :auto_registrar, default: AutoRegistrar
22
23
 
23
24
  def self.injector(effects: true, **kwargs)
24
25
  if effects
@@ -34,7 +35,7 @@ module Dry
34
35
  super
35
36
 
36
37
  # Force all components to load
37
- each_key { |key| resolve(key) }
38
+ each_key { resolve(_1) }
38
39
  self
39
40
  end
40
41
  end
@@ -1,23 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/core/extensions'
4
-
5
3
  Dry::Effects.extend(Dry::Core::Extensions)
6
4
 
7
5
  Dry::Effects.register_extension(:auto_inject) do
8
- require 'dry/effects/extensions/auto_inject'
6
+ require "dry/effects/extensions/auto_inject"
9
7
  end
10
8
 
11
9
  Dry::Effects.register_extension(:system) do
12
- require 'dry/effects/extensions/system'
10
+ require "dry/effects/extensions/system"
13
11
  end
14
12
 
15
13
  Dry::Effects.register_extension(:rspec) do
16
- require 'dry/effects/extensions/rspec'
14
+ require "dry/effects/extensions/rspec"
17
15
  end
18
16
 
19
17
  Dry::Effects.register_extension(:active_support_tagged_logging) do
20
- require 'dry/effects/extensions/active_support/tagged_logging'
18
+ require "dry/effects/extensions/active_support/tagged_logging"
21
19
  end
22
20
 
23
21
  Dry::Effects.register_extension(:active_support) do
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fiber'
4
- require 'dry/effects/initializer'
5
- require 'dry/effects/effect'
6
- require 'dry/effects/errors'
7
- require 'dry/effects/stack'
8
- require 'dry/effects/instructions/raise'
3
+ require "fiber"
4
+ require "dry/effects/initializer"
5
+ require "dry/effects/effect"
6
+ require "dry/effects/errors"
7
+ require "dry/effects/stack"
8
+ require "dry/effects/instructions/raise"
9
9
 
10
10
  module Dry
11
11
  module Effects
@@ -41,17 +41,31 @@ module Dry
41
41
  result = fiber.resume
42
42
 
43
43
  loop do
44
+ error = false
44
45
  break result unless fiber.alive?
45
46
 
46
47
  provided = stack.(result) do
47
- ::Dry::Effects.yield(result) do |_, error|
48
- Instructions.Raise(error)
48
+ ::Dry::Effects.yield(result) do |_, e|
49
+ error = true
50
+ e
49
51
  end
50
52
  end
51
53
 
52
- result = fiber.resume(provided)
54
+ result =
55
+ if error
56
+ raise_in_fiber(fiber, provided)
57
+ else
58
+ fiber.resume(provided)
59
+ end
53
60
  end
54
61
  end
62
+
63
+ private
64
+
65
+ # @api private
66
+ def raise_in_fiber(fiber, error)
67
+ fiber.raise(error)
68
+ end
55
69
  end
56
70
 
57
71
  extend Initializer
@@ -1,8 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'concurrent/map'
4
- require 'dry/core/class_attributes'
5
- require 'dry/effects/inflector'
3
+ require "concurrent/map"
4
+ require "dry/effects/inflector"
6
5
 
7
6
  module Dry
8
7
  module Effects
@@ -12,16 +12,8 @@ module Dry
12
12
  @frame = Frame.new(provider)
13
13
  end
14
14
 
15
- if RUBY_VERSION >= '2.7'
16
- class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
17
- def call(...)
18
- frame.(...)
19
- end
20
- RUBY
21
- else
22
- def call(*args, &block)
23
- frame.(*args, &block)
24
- end
15
+ def call(...)
16
+ frame.(...)
25
17
  end
26
18
 
27
19
  def to_s
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/inflector'
3
+ require "dry/inflector"
4
4
 
5
5
  module Dry
6
6
  module Effects
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/initializer'
3
+ require "dry/initializer"
4
4
 
5
5
  module Dry
6
6
  module Effects
@@ -27,12 +27,10 @@ module Dry
27
27
 
28
28
  # @api private
29
29
  def params_arity
30
- @params_arity ||= begin
31
- dry_initializer
32
- .definitions
33
- .reject { |_, d| d.option }
34
- .size
35
- end
30
+ @params_arity ||= dry_initializer
31
+ .definitions
32
+ .reject { _2.option }
33
+ .size
36
34
  end
37
35
 
38
36
  # @api private
@@ -46,22 +44,22 @@ module Dry
46
44
  def __define_with__
47
45
  seq_names = dry_initializer
48
46
  .definitions
49
- .reject { |_, d| d.option }
47
+ .reject { _2.option }
50
48
  .keys
51
- .join(', ')
49
+ .join(", ")
52
50
 
53
- seq_names << ', ' unless seq_names.empty?
51
+ seq_names << ", " unless seq_names.empty?
54
52
 
55
53
  undef_method(:with) if method_defined?(:with)
56
54
 
57
55
  class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
58
- def with(**new_options)
59
- if new_options.empty?
60
- self
61
- else
62
- self.class.new(#{seq_names}**options, **new_options)
63
- end
64
- end
56
+ def with(**new_options) # def with(**new_options)
57
+ if new_options.empty? # if new_options.empty?
58
+ self # self
59
+ else # else
60
+ self.class.new(#{seq_names}**options, **new_options) # self.class.new(attr1, attr2, **options, **new_options)
61
+ end # end
62
+ end # end
65
63
  RUBY
66
64
  end
67
65
  end
@@ -81,9 +79,11 @@ module Dry
81
79
  #
82
80
  # @api public
83
81
  def options
82
+ # rubocop:disable Layout/LineLength
84
83
  @__options__ ||= self.class.dry_initializer.definitions.values.each_with_object({}) do |item, obj|
85
84
  obj[item.target] = instance_variable_get(item.ivar)
86
85
  end
86
+ # rubocop:enable Layout/LineLength
87
87
  end
88
88
 
89
89
  define_method(:class, Kernel.instance_method(:class))
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/effects/instruction'
3
+ require "dry/effects/instruction"
4
4
 
5
5
  module Dry
6
6
  module Effects
@@ -9,6 +9,7 @@ module Dry
9
9
  attr_reader :block
10
10
 
11
11
  def initialize(block)
12
+ super()
12
13
  @block = block
13
14
  end
14
15
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/effects/instruction'
3
+ require "dry/effects/instruction"
4
4
 
5
5
  module Dry
6
6
  module Effects
@@ -9,6 +9,7 @@ module Dry
9
9
  attr_reader :error
10
10
 
11
11
  def initialize(error)
12
+ super()
12
13
  @error = error
13
14
  end
14
15
 
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/core/class_attributes'
4
- require 'dry/effects/frame'
3
+ require "dry/effects/frame"
5
4
 
6
5
  module Dry
7
6
  module Effects
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/effects/initializer'
4
- require 'dry/effects/provider/class_interface'
3
+ require "dry/effects/initializer"
4
+ require "dry/effects/provider/class_interface"
5
5
 
6
6
  module Dry
7
7
  module Effects
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/effects/provider'
4
- require 'dry/effects/frame'
3
+ require "dry/effects/provider"
4
+ require "dry/effects/frame"
5
5
 
6
6
  module Dry
7
7
  module Effects
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/effects/provider'
4
- require 'dry/effects/instructions/execute'
3
+ require "dry/effects/provider"
4
+ require "dry/effects/instructions/execute"
5
5
 
6
6
  module Dry
7
7
  module Effects
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/effects/provider'
3
+ require "dry/effects/provider"
4
4
 
5
5
  module Dry
6
6
  module Effects
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/effects/provider'
3
+ require "dry/effects/provider"
4
4
 
5
5
  module Dry
6
6
  module Effects
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'time'
4
- require 'dry/effects/provider'
5
- require 'dry/effects/providers/current_time/time_generators'
3
+ require "time"
4
+ require "dry/effects/provider"
5
+ require "dry/effects/providers/current_time/time_generators"
6
6
 
7
7
  module Dry
8
8
  module Effects
@@ -55,12 +55,12 @@ module Dry
55
55
  def represent
56
56
  if fixed?
57
57
  if generator.nil?
58
- 'current_time[fixed=true]'
58
+ "current_time[fixed=true]"
59
59
  else
60
60
  "current_time[fixed=#{generator.().iso8601(6)}]"
61
61
  end
62
62
  else
63
- 'current_time[fixed=false]'
63
+ "current_time[fixed=false]"
64
64
  end
65
65
  end
66
66
 
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'concurrent/promise'
4
- require 'dry/effects/provider'
5
- require 'dry/effects/frame'
3
+ require "concurrent/promise"
4
+ require "dry/effects/provider"
5
+ require "dry/effects/frame"
6
6
 
7
7
  module Dry
8
8
  module Effects
@@ -51,7 +51,7 @@ module Dry
51
51
  # Yield the block with the handler installed
52
52
  #
53
53
  # @api private
54
- def call(options = { executor: Undefined })
54
+ def call(options = {executor: Undefined})
55
55
  unless Undefined.equal?(options[:executor])
56
56
  @executor = options[:executor]
57
57
  end
@@ -65,7 +65,7 @@ module Dry
65
65
 
66
66
  def dup
67
67
  if defined? @later_calls
68
- super.tap { |p| p.instance_variable_set(:@later_calls, EMPTY_ARRAY) }
68
+ super.tap { _1.instance_variable_set(:@later_calls, EMPTY_ARRAY) }
69
69
  else
70
70
  super
71
71
  end
@@ -79,9 +79,9 @@ module Dry
79
79
  info << "call_later=#{later_calls.size}" if later_calls.any?
80
80
 
81
81
  if info.empty?
82
- 'defer'
82
+ "defer"
83
83
  else
84
- "defer[#{info.join(' ')}]"
84
+ "defer[#{info.join(" ")}]"
85
85
  end
86
86
  end
87
87
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/effects/provider'
4
- require 'dry/effects/instructions/raise'
3
+ require "dry/effects/provider"
4
+ require "dry/effects/instructions/raise"
5
5
 
6
6
  module Dry
7
7
  module Effects
@@ -67,7 +67,7 @@ module Dry
67
67
  end
68
68
 
69
69
  def key?(key)
70
- values.key?(key) || key.is_a?(::String) && ::ENV.key?(key) || parent.key?(key)
70
+ values.key?(key) || (key.is_a?(::String) && ::ENV.key?(key)) || parent.key?(key)
71
71
  end
72
72
  end
73
73
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/effects/provider'
4
- require 'dry/effects/frame'
3
+ require "dry/effects/provider"
4
+ require "dry/effects/frame"
5
5
 
6
6
  module Dry
7
7
  module Effects
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/effects/provider'
3
+ require "dry/effects/provider"
4
4
 
5
5
  module Dry
6
6
  module Effects
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/effects/provider'
4
- require 'dry/effects/instructions/raise'
5
- require 'dry/effects/halt'
3
+ require "dry/effects/provider"
4
+ require "dry/effects/instructions/raise"
5
+ require "dry/effects/halt"
6
6
 
7
7
  module Dry
8
8
  module Effects
@@ -1,8 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/equalizer'
4
- require 'dry/effects/provider'
5
- require 'dry/effects/initializer'
3
+ require "dry/effects/provider"
4
+ require "dry/effects/initializer"
6
5
 
7
6
  module Dry
8
7
  module Effects
@@ -96,11 +95,9 @@ module Dry
96
95
  end
97
96
 
98
97
  with_backend(backend_replace) do
99
- begin
100
- yield
101
- ensure
102
- owned.each { |handle| unlock(handle) }
103
- end
98
+ yield
99
+ ensure
100
+ owned.each { unlock(_1) }
104
101
  end
105
102
  end
106
103
 
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'concurrent/promise'
4
- require 'dry/effects/provider'
5
- require 'dry/effects/frame'
3
+ require "concurrent/promise"
4
+ require "dry/effects/provider"
5
+ require "dry/effects/frame"
6
6
 
7
7
  module Dry
8
8
  module Effects
@@ -1,14 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/effects/provider'
3
+ require "dry/effects/provider"
4
4
 
5
5
  module Dry
6
6
  module Effects
7
7
  module Providers
8
8
  class Random < Provider[:random]
9
- DEFAULT = -> _ { ::Random::DEFAULT.rand }
9
+ DEFAULT_RANDOM = ::Random
10
+ DEFAULT = -> _ { DEFAULT_RANDOM.rand }
10
11
 
11
- DEFAULT_RANGE = 0.0...1.0
12
+ DEFAULT_RANGE = (0.0...1.0).freeze
12
13
 
13
14
  def rand(range_or_limit = nil)
14
15
  range_or_limit ||= DEFAULT_RANGE
@@ -66,7 +67,7 @@ module Dry
66
67
  if options.key?(:seed)
67
68
  random = ::Random.new(options[:seed])
68
69
  else
69
- random = ::Random::DEFAULT
70
+ random = DEFAULT_RANDOM
70
71
  end
71
72
 
72
73
  -> _ { random.rand }
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/effects/provider'
3
+ require "dry/effects/provider"
4
4
 
5
5
  module Dry
6
6
  module Effects
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/effects/provider'
4
- require 'dry/effects/instructions/raise'
3
+ require "dry/effects/provider"
4
+ require "dry/effects/instructions/raise"
5
5
 
6
6
  module Dry
7
7
  module Effects
@@ -84,16 +84,17 @@ module Dry
84
84
  # @return [String]
85
85
  # @api public
86
86
  def represent
87
- containers = [represent_container(static), represent_container(dynamic)].compact.join('+')
88
- "resolve[#{containers.empty? ? 'empty' : containers}]"
87
+ containers = [represent_container(static), represent_container(dynamic)].compact.join("+")
88
+ "resolve[#{containers.empty? ? "empty" : containers}]"
89
89
  end
90
90
 
91
91
  # @return [String]
92
92
  # @api private
93
93
  def represent_container(container)
94
- if container.is_a?(::Hash)
95
- container.empty? ? nil : 'hash'
96
- elsif container.is_a?(::Class)
94
+ case container
95
+ when ::Hash
96
+ container.empty? ? nil : "hash"
97
+ when ::Class
97
98
  container.name || container.to_s
98
99
  else
99
100
  container.to_s
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/effects/provider'
4
- require 'dry/effects/halt'
3
+ require "dry/effects/provider"
4
+ require "dry/effects/halt"
5
5
 
6
6
  module Dry
7
7
  module Effects
@@ -18,15 +18,13 @@ module Dry
18
18
  # Yield the block with the handler installed
19
19
  #
20
20
  # @api private
21
- def call(limit)
21
+ def call(limit, &block)
22
22
  @limit = limit
23
23
  @attempts = 0
24
24
 
25
25
  loop do
26
- begin
27
- return attempt { yield }
28
- rescue halt
29
- end
26
+ return attempt(&block)
27
+ rescue halt # rubocop:disable Lint/SuppressedException
30
28
  end
31
29
  end
32
30
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/effects/providers/reader'
4
- require 'dry/effects/instructions/raise'
3
+ require "dry/effects/providers/reader"
4
+ require "dry/effects/instructions/raise"
5
5
 
6
6
  module Dry
7
7
  module Effects
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/effects/provider'
3
+ require "dry/effects/provider"
4
4
 
5
5
  module Dry
6
6
  module Effects
7
7
  module Providers
8
8
  class Timeout < Provider[:timeout]
9
- def self.handle_method(scope, as: Undefined, **)
9
+ def self.handle_method(_scope, as: Undefined, **)
10
10
  Undefined.default(as) { :with_timeout }
11
11
  end
12
12
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/effects/provider'
4
- require 'dry/effects/providers/current_time'
3
+ require "dry/effects/provider"
4
+ require "dry/effects/providers/current_time"
5
5
 
6
6
  module Dry
7
7
  module Effects