dry-types 1.2.2 → 1.5.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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +405 -225
  3. data/LICENSE +1 -1
  4. data/README.md +14 -12
  5. data/dry-types.gemspec +26 -31
  6. data/lib/dry-types.rb +1 -1
  7. data/lib/dry/types.rb +55 -40
  8. data/lib/dry/types/any.rb +2 -2
  9. data/lib/dry/types/array.rb +2 -2
  10. data/lib/dry/types/array/constructor.rb +1 -1
  11. data/lib/dry/types/array/member.rb +1 -1
  12. data/lib/dry/types/builder.rb +70 -18
  13. data/lib/dry/types/builder_methods.rb +1 -2
  14. data/lib/dry/types/coercions.rb +0 -17
  15. data/lib/dry/types/coercions/json.rb +22 -5
  16. data/lib/dry/types/coercions/params.rb +20 -3
  17. data/lib/dry/types/compiler.rb +10 -10
  18. data/lib/dry/types/constrained.rb +6 -9
  19. data/lib/dry/types/constraints.rb +3 -3
  20. data/lib/dry/types/constructor.rb +40 -6
  21. data/lib/dry/types/constructor/function.rb +48 -32
  22. data/lib/dry/types/constructor/wrapper.rb +94 -0
  23. data/lib/dry/types/container.rb +1 -1
  24. data/lib/dry/types/core.rb +15 -13
  25. data/lib/dry/types/decorator.rb +2 -9
  26. data/lib/dry/types/default.rb +14 -1
  27. data/lib/dry/types/enum.rb +4 -3
  28. data/lib/dry/types/errors.rb +1 -1
  29. data/lib/dry/types/extensions.rb +2 -2
  30. data/lib/dry/types/extensions/maybe.rb +18 -17
  31. data/lib/dry/types/extensions/monads.rb +1 -1
  32. data/lib/dry/types/fn_container.rb +1 -1
  33. data/lib/dry/types/hash.rb +9 -15
  34. data/lib/dry/types/hash/constructor.rb +1 -1
  35. data/lib/dry/types/inflector.rb +1 -1
  36. data/lib/dry/types/json.rb +15 -15
  37. data/lib/dry/types/lax.rb +3 -6
  38. data/lib/dry/types/map.rb +2 -2
  39. data/lib/dry/types/meta.rb +3 -3
  40. data/lib/dry/types/module.rb +6 -6
  41. data/lib/dry/types/nominal.rb +11 -11
  42. data/lib/dry/types/params.rb +31 -28
  43. data/lib/dry/types/predicate_inferrer.rb +52 -11
  44. data/lib/dry/types/predicate_registry.rb +1 -1
  45. data/lib/dry/types/primitive_inferrer.rb +1 -1
  46. data/lib/dry/types/printer.rb +25 -25
  47. data/lib/dry/types/result.rb +3 -3
  48. data/lib/dry/types/schema.rb +26 -13
  49. data/lib/dry/types/schema/key.rb +15 -6
  50. data/lib/dry/types/spec/types.rb +65 -42
  51. data/lib/dry/types/sum.rb +6 -5
  52. data/lib/dry/types/type.rb +1 -1
  53. data/lib/dry/types/version.rb +1 -1
  54. metadata +27 -78
  55. data/.codeclimate.yml +0 -12
  56. data/.github/ISSUE_TEMPLATE/----please-don-t-ask-for-support-via-issues.md +0 -10
  57. data/.github/ISSUE_TEMPLATE/---bug-report.md +0 -30
  58. data/.github/ISSUE_TEMPLATE/---feature-request.md +0 -18
  59. data/.github/workflows/custom_ci.yml +0 -76
  60. data/.github/workflows/docsite.yml +0 -34
  61. data/.github/workflows/sync_configs.yml +0 -34
  62. data/.gitignore +0 -11
  63. data/.rspec +0 -4
  64. data/.rubocop.yml +0 -92
  65. data/.yardopts +0 -9
  66. data/CODE_OF_CONDUCT.md +0 -13
  67. data/CONTRIBUTING.md +0 -29
  68. data/Gemfile +0 -34
  69. data/Rakefile +0 -22
  70. data/benchmarks/hash_schemas.rb +0 -55
  71. data/benchmarks/lax_schema.rb +0 -15
  72. data/benchmarks/profile_invalid_input.rb +0 -15
  73. data/benchmarks/profile_lax_schema_valid.rb +0 -16
  74. data/benchmarks/profile_valid_input.rb +0 -15
  75. data/benchmarks/schema_valid_vs_invalid.rb +0 -21
  76. data/benchmarks/setup.rb +0 -17
  77. data/docsite/source/array-with-member.html.md +0 -13
  78. data/docsite/source/built-in-types.html.md +0 -116
  79. data/docsite/source/constraints.html.md +0 -31
  80. data/docsite/source/custom-types.html.md +0 -93
  81. data/docsite/source/default-values.html.md +0 -91
  82. data/docsite/source/enum.html.md +0 -69
  83. data/docsite/source/extensions.html.md +0 -15
  84. data/docsite/source/extensions/maybe.html.md +0 -57
  85. data/docsite/source/extensions/monads.html.md +0 -61
  86. data/docsite/source/getting-started.html.md +0 -57
  87. data/docsite/source/hash-schemas.html.md +0 -169
  88. data/docsite/source/index.html.md +0 -156
  89. data/docsite/source/map.html.md +0 -17
  90. data/docsite/source/optional-values.html.md +0 -35
  91. data/docsite/source/sum.html.md +0 -21
@@ -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 Types
@@ -1,35 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/types/coercions/json'
3
+ require "dry/types/coercions/json"
4
4
 
5
5
  module Dry
6
6
  module Types
7
- register('json.nil') do
8
- self['nominal.nil'].constructor(Coercions::JSON.method(:to_nil))
7
+ register("json.nil") do
8
+ self["nominal.nil"].constructor(Coercions::JSON.method(:to_nil))
9
9
  end
10
10
 
11
- register('json.date') do
12
- self['nominal.date'].constructor(Coercions::JSON.method(:to_date))
11
+ register("json.date") do
12
+ self["nominal.date"].constructor(Coercions::JSON.method(:to_date))
13
13
  end
14
14
 
15
- register('json.date_time') do
16
- self['nominal.date_time'].constructor(Coercions::JSON.method(:to_date_time))
15
+ register("json.date_time") do
16
+ self["nominal.date_time"].constructor(Coercions::JSON.method(:to_date_time))
17
17
  end
18
18
 
19
- register('json.time') do
20
- self['nominal.time'].constructor(Coercions::JSON.method(:to_time))
19
+ register("json.time") do
20
+ self["nominal.time"].constructor(Coercions::JSON.method(:to_time))
21
21
  end
22
22
 
23
- register('json.decimal') do
24
- self['nominal.decimal'].constructor(Coercions::JSON.method(:to_decimal))
23
+ register("json.decimal") do
24
+ self["nominal.decimal"].constructor(Coercions::JSON.method(:to_decimal))
25
25
  end
26
26
 
27
- register('json.symbol') do
28
- self['nominal.symbol'].constructor(Coercions::JSON.method(:to_symbol))
27
+ register("json.symbol") do
28
+ self["nominal.symbol"].constructor(Coercions::JSON.method(:to_symbol))
29
29
  end
30
30
 
31
- register('json.array') { self['array'] }
31
+ register("json.array") { self["array"] }
32
32
 
33
- register('json.hash') { self['hash'] }
33
+ register("json.hash") { self["hash"] }
34
34
  end
35
35
  end
data/lib/dry/types/lax.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/core/deprecations'
4
- require 'dry/types/decorator'
3
+ require "dry/core/deprecations"
4
+ require "dry/types/decorator"
5
5
 
6
6
  module Dry
7
7
  module Types
@@ -15,7 +15,7 @@ module Dry
15
15
  include Printable
16
16
  include Dry::Equalizer(:type, inspect: false, immutable: true)
17
17
 
18
- undef :options, :constructor
18
+ undef :options, :constructor, :<<, :>>, :prepend, :append
19
19
 
20
20
  # @param [Object] input
21
21
  #
@@ -40,9 +40,6 @@ module Dry
40
40
  # @api public
41
41
  def try(input, &block)
42
42
  type.try(input, &block)
43
- rescue CoercionError => e
44
- result = failure(input, e.message)
45
- block ? yield(result) : result
46
43
  end
47
44
 
48
45
  # @see Nominal#to_ast
data/lib/dry/types/map.rb CHANGED
@@ -21,7 +21,7 @@ module Dry
21
21
  #
22
22
  # @api public
23
23
  class Map < Nominal
24
- def initialize(_primitive, key_type: Types['any'], value_type: Types['any'], meta: EMPTY_HASH)
24
+ def initialize(_primitive, key_type: Types["any"], value_type: Types["any"], meta: EMPTY_HASH)
25
25
  super(_primitive, key_type: key_type, value_type: value_type, meta: meta)
26
26
  end
27
27
 
@@ -43,7 +43,7 @@ module Dry
43
43
  #
44
44
  # @api public
45
45
  def name
46
- 'Map'
46
+ "Map"
47
47
  end
48
48
 
49
49
  # @param [Hash] hash
@@ -11,7 +11,7 @@ module Dry
11
11
  @meta = meta.freeze
12
12
  end
13
13
 
14
- # @param [Hash] new_options
14
+ # @param options [Hash] new_options
15
15
  #
16
16
  # @return [Type]
17
17
  #
@@ -28,8 +28,8 @@ module Dry
28
28
  # @return [Type] new type with added metadata
29
29
  #
30
30
  # @api public
31
- def meta(data = nil)
32
- if !data
31
+ def meta(data = Undefined)
32
+ if Undefined.equal?(data)
33
33
  @meta
34
34
  elsif data.empty?
35
35
  self
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/core/deprecations'
4
- require 'dry/types/builder_methods'
3
+ require "dry/core/deprecations"
4
+ require "dry/types/builder_methods"
5
5
 
6
6
  module Dry
7
7
  module Types
@@ -31,7 +31,7 @@ module Dry
31
31
  base.instance_exec(const_get(:Nominal, false)) do |nominal|
32
32
  extend Dry::Core::Deprecations[:'dry-types']
33
33
  const_set(:Definition, nominal)
34
- deprecate_constant(:Definition, message: 'Nominal')
34
+ deprecate_constant(:Definition, message: "Nominal")
35
35
  end
36
36
  end
37
37
  end
@@ -69,7 +69,7 @@ module Dry
69
69
  def registry_tree
70
70
  @registry_tree ||= @registry.keys.each_with_object({}) { |key, tree|
71
71
  type = @registry[key]
72
- *modules, const_name = key.split('.').map { |part|
72
+ *modules, const_name = key.split(".").map { |part|
73
73
  Inflector.camelize(part).to_sym
74
74
  }
75
75
  next if modules.empty?
@@ -87,14 +87,14 @@ module Dry
87
87
  referenced.concat(aliases.keys)
88
88
 
89
89
  known = @registry.keys.map { |k|
90
- ns, *path = k.split('.')
90
+ ns, *path = k.split(".")
91
91
  ns.to_sym unless path.empty?
92
92
  }.compact.uniq
93
93
 
94
94
  (referenced.uniq - known).each do |name|
95
95
  raise ArgumentError,
96
96
  "#{name.inspect} is not a known type namespace. "\
97
- "Supported options are #{known.map(&:inspect).join(', ')}"
97
+ "Supported options are #{known.map(&:inspect).join(", ")}"
98
98
  end
99
99
  end
100
100
 
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/core/deprecations'
4
- require 'dry/types/builder'
5
- require 'dry/types/result'
6
- require 'dry/types/options'
7
- require 'dry/types/meta'
3
+ require "dry/core/deprecations"
4
+ require "dry/core/equalizer"
5
+ require "dry/types/builder"
6
+ require "dry/types/result"
7
+ require "dry/types/options"
8
+ require "dry/types/meta"
8
9
 
9
10
  module Dry
10
11
  module Types
@@ -98,7 +99,6 @@ module Dry
98
99
  end
99
100
 
100
101
  # @param [Object] input
101
- # @param [#call,nil] block
102
102
  #
103
103
  # @yieldparam [Failure] failure
104
104
  # @yieldreturn [Result]
@@ -126,7 +126,7 @@ module Dry
126
126
  #
127
127
  # @api public
128
128
  def failure(input, error)
129
- raise ArgumentError, 'error must be a CoercionError' unless error.is_a?(CoercionError)
129
+ raise ArgumentError, "error must be a CoercionError" unless error.is_a?(CoercionError)
130
130
 
131
131
  Result::Failure.new(input, error)
132
132
  end
@@ -201,10 +201,10 @@ module Dry
201
201
 
202
202
  extend Dry::Core::Deprecations[:'dry-types']
203
203
  Definition = Nominal
204
- deprecate_constant(:Definition, message: 'Nominal')
204
+ deprecate_constant(:Definition, message: "Nominal")
205
205
  end
206
206
  end
207
207
 
208
- require 'dry/types/array'
209
- require 'dry/types/hash'
210
- require 'dry/types/map'
208
+ require "dry/types/array"
209
+ require "dry/types/hash"
210
+ require "dry/types/map"
@@ -1,64 +1,67 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/types/coercions/params'
3
+ require "dry/types/coercions/params"
4
4
 
5
5
  module Dry
6
6
  module Types
7
- register('params.nil') do
8
- self['nominal.nil'].constructor(Coercions::Params.method(:to_nil))
7
+ register("params.nil") do
8
+ self["nominal.nil"].constructor(Coercions::Params.method(:to_nil))
9
9
  end
10
10
 
11
- register('params.date') do
12
- self['nominal.date'].constructor(Coercions::Params.method(:to_date))
11
+ register("params.date") do
12
+ self["nominal.date"].constructor(Coercions::Params.method(:to_date))
13
13
  end
14
14
 
15
- register('params.date_time') do
16
- self['nominal.date_time'].constructor(Coercions::Params.method(:to_date_time))
15
+ register("params.date_time") do
16
+ self["nominal.date_time"].constructor(Coercions::Params.method(:to_date_time))
17
17
  end
18
18
 
19
- register('params.time') do
20
- self['nominal.time'].constructor(Coercions::Params.method(:to_time))
19
+ register("params.time") do
20
+ self["nominal.time"].constructor(Coercions::Params.method(:to_time))
21
21
  end
22
22
 
23
- register('params.true') do
24
- self['nominal.true'].constructor(Coercions::Params.method(:to_true))
23
+ register("params.true") do
24
+ self["nominal.true"].constructor(Coercions::Params.method(:to_true))
25
25
  end
26
26
 
27
- register('params.false') do
28
- self['nominal.false'].constructor(Coercions::Params.method(:to_false))
27
+ register("params.false") do
28
+ self["nominal.false"].constructor(Coercions::Params.method(:to_false))
29
29
  end
30
30
 
31
- register('params.bool') do
32
- self['params.true'] | self['params.false']
31
+ register("params.bool") do
32
+ self["params.true"] | self["params.false"]
33
33
  end
34
34
 
35
- register('params.integer') do
36
- self['nominal.integer'].constructor(Coercions::Params.method(:to_int))
35
+ register("params.integer") do
36
+ self["nominal.integer"].constructor(Coercions::Params.method(:to_int))
37
37
  end
38
38
 
39
- register('params.float') do
40
- self['nominal.float'].constructor(Coercions::Params.method(:to_float))
39
+ register("params.float") do
40
+ self["nominal.float"].constructor(Coercions::Params.method(:to_float))
41
41
  end
42
42
 
43
- register('params.decimal') do
44
- self['nominal.decimal'].constructor(Coercions::Params.method(:to_decimal))
43
+ register("params.decimal") do
44
+ self["nominal.decimal"].constructor(Coercions::Params.method(:to_decimal))
45
45
  end
46
46
 
47
- register('params.array') do
48
- self['nominal.array'].constructor(Coercions::Params.method(:to_ary))
47
+ register("params.array") do
48
+ self["nominal.array"].constructor(Coercions::Params.method(:to_ary))
49
49
  end
50
50
 
51
- register('params.hash') do
52
- self['nominal.hash'].constructor(Coercions::Params.method(:to_hash))
51
+ register("params.hash") do
52
+ self["nominal.hash"].constructor(Coercions::Params.method(:to_hash))
53
53
  end
54
54
 
55
- register('params.symbol') do
56
- self['nominal.symbol'].constructor(Coercions::Params.method(:to_symbol))
55
+ register("params.symbol") do
56
+ self["nominal.symbol"].constructor(Coercions::Params.method(:to_symbol))
57
57
  end
58
58
 
59
+ register("params.string", self["string"])
60
+
59
61
  COERCIBLE.each_key do |name|
60
62
  next if name.equal?(:string)
61
- register("optional.params.#{name}", self['params.nil'] | self["params.#{name}"])
63
+
64
+ register("optional.params.#{name}", self["params.nil"] | self["params.#{name}"])
62
65
  end
63
66
  end
64
67
  end
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/core/cache'
4
- require 'dry/types/predicate_registry'
3
+ require "dry/core/cache"
4
+ require "dry/core/class_attributes"
5
+ require "dry/types/predicate_registry"
5
6
 
6
7
  module Dry
7
8
  module Types
@@ -12,13 +13,17 @@ module Dry
12
13
  extend Core::Cache
13
14
 
14
15
  TYPE_TO_PREDICATE = {
15
- DateTime => :date_time?,
16
- FalseClass => :false?,
17
- Integer => :int?,
18
- NilClass => :nil?,
19
- String => :str?,
20
- TrueClass => :true?,
21
- BigDecimal => :decimal?
16
+ ::DateTime => :date_time?,
17
+ ::Date => :date?,
18
+ ::Time => :time?,
19
+ ::FalseClass => :false?,
20
+ ::Integer => :int?,
21
+ ::Float => :float?,
22
+ ::NilClass => :nil?,
23
+ ::String => :str?,
24
+ ::TrueClass => :true?,
25
+ ::BigDecimal => :decimal?,
26
+ ::Array => :array?
22
27
  }.freeze
23
28
 
24
29
  REDUCED_TYPES = {
@@ -35,6 +40,11 @@ module Dry
35
40
  #
36
41
  # @api private
37
42
  class Compiler
43
+ extend Core::ClassAttributes
44
+
45
+ defines :infer_predicate_by_class_name
46
+ infer_predicate_by_class_name nil
47
+
38
48
  # @return [PredicateRegistry]
39
49
  # @api private
40
50
  attr_reader :registry
@@ -46,7 +56,37 @@ module Dry
46
56
 
47
57
  # @api private
48
58
  def infer_predicate(type)
49
- [TYPE_TO_PREDICATE.fetch(type) { :"#{type.name.split('::').last.downcase}?" }]
59
+ pred = TYPE_TO_PREDICATE.fetch(type) do
60
+ if type.name.nil? || self.class.infer_predicate_by_class_name.equal?(false)
61
+ nil
62
+ else
63
+ candidate = :"#{type.name.split("::").last.downcase}?"
64
+
65
+ if registry.key?(candidate)
66
+ if self.class.infer_predicate_by_class_name
67
+ candidate
68
+ else
69
+ raise ::KeyError, <<~MESSAGE
70
+ Automatic predicate inferring from class names is deprecated
71
+ and will be removed in dry-types 2.0.
72
+ Use `Dry::Types::PredicateInferrer::Compiler.infer_predicate_by_class_name true`
73
+ to restore the previous behavior
74
+ or `Dry::Types::PredicateInferrer::Compiler.infer_predicate_by_class_name false`
75
+ to explicitly opt-out (i.e. no exception + no inferring).
76
+ Note: for dry-schema and dry-validation use Dry::Schema::PredicateInferrer::Compiler.
77
+ MESSAGE
78
+ end
79
+ else
80
+ nil
81
+ end
82
+ end
83
+ end
84
+
85
+ if pred.nil?
86
+ EMPTY_ARRAY
87
+ else
88
+ [pred]
89
+ end
50
90
  end
51
91
 
52
92
  # @api private
@@ -60,7 +100,7 @@ module Dry
60
100
  type = node[0]
61
101
  predicate = infer_predicate(type)
62
102
 
63
- if registry.key?(predicate[0])
103
+ if !predicate.empty? && registry.key?(predicate[0])
64
104
  predicate
65
105
  else
66
106
  [type?: type]
@@ -71,6 +111,7 @@ module Dry
71
111
  def visit_hash(_)
72
112
  HASH
73
113
  end
114
+ alias_method :visit_schema, :visit_hash
74
115
 
75
116
  # @api private
76
117
  def visit_array(_)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/logic/predicates'
3
+ require "dry/logic/predicates"
4
4
 
5
5
  module Dry
6
6
  module Types
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/core/cache'
3
+ require "dry/core/cache"
4
4
 
5
5
  module Dry
6
6
  module Types
@@ -7,8 +7,6 @@ module Dry
7
7
  MAPPING = {
8
8
  Nominal => :visit_nominal,
9
9
  Constructor => :visit_constructor,
10
- Hash::Constructor => :visit_constructor,
11
- Array::Constructor => :visit_constructor,
12
10
  Constrained => :visit_constrained,
13
11
  Constrained::Coercible => :visit_constrained,
14
12
  Hash => :visit_hash,
@@ -27,14 +25,16 @@ module Dry
27
25
  }
28
26
 
29
27
  def call(type)
30
- output = ''.dup
28
+ output = "".dup
31
29
  visit(type) { |str| output << str }
32
30
  "#<Dry::Types[#{output}]>"
33
31
  end
34
32
 
35
33
  def visit(type, &block)
36
34
  print_with = MAPPING.fetch(type.class) do
37
- if type.is_a?(Type)
35
+ if type.class < Constructor
36
+ :visit_constructor
37
+ elsif type.is_a?(Type)
38
38
  return yield type.inspect
39
39
  else
40
40
  raise ArgumentError, "Do not know how to print #{type.class}"
@@ -44,7 +44,7 @@ module Dry
44
44
  end
45
45
 
46
46
  def visit_any(_)
47
- yield 'Any'
47
+ yield "Any"
48
48
  end
49
49
 
50
50
  def visit_array(type)
@@ -88,11 +88,11 @@ module Dry
88
88
  def visit_schema(schema)
89
89
  options = schema.options.dup
90
90
  size = schema.count
91
- key_fn_str = ''
92
- type_fn_str = ''
93
- strict_str = ''
91
+ key_fn_str = ""
92
+ type_fn_str = ""
93
+ strict_str = ""
94
94
 
95
- strict_str = 'strict ' if options.delete(:strict)
95
+ strict_str = "strict " if options.delete(:strict)
96
96
 
97
97
  if key_fn = options.delete(:key_transform_fn)
98
98
  visit_callable(key_fn) do |fn|
@@ -119,7 +119,7 @@ module Dry
119
119
  else
120
120
  yield header.dup << keys.map { |key|
121
121
  visit(key) { |type| type }
122
- }.join(' ') << '}>'
122
+ }.join(" ") << "}>"
123
123
  end
124
124
  end
125
125
  end
@@ -194,12 +194,12 @@ module Dry
194
194
 
195
195
  visit_options(options) do |opts|
196
196
  if mapping == enum.inverted_mapping
197
- values = mapping.values.map(&:inspect).join(', ')
197
+ values = mapping.values.map(&:inspect).join(", ")
198
198
  yield "Enum<#{type} values={#{values}}#{opts}>"
199
199
  else
200
200
  mapping_str = mapping.map { |key, value|
201
201
  "#{key.inspect}=>#{value.inspect}"
202
- }.join(', ')
202
+ }.join(", ")
203
203
  yield "Enum<#{type} mapping={#{mapping_str}}#{opts}>"
204
204
  end
205
205
  end
@@ -234,7 +234,7 @@ module Dry
234
234
 
235
235
  def visit_hash(hash)
236
236
  options = hash.options.dup
237
- type_fn_str = ''
237
+ type_fn_str = ""
238
238
 
239
239
  if type_fn = options.delete(:type_transform_fn)
240
240
  visit_callable(type_fn) do |fn|
@@ -244,7 +244,7 @@ module Dry
244
244
 
245
245
  visit_options(options, hash.meta) do |opts|
246
246
  if opts.empty? && type_fn_str.empty?
247
- yield 'Hash'
247
+ yield "Hash"
248
248
  else
249
249
  yield "Hash<#{type_fn_str}#{opts}>"
250
250
  end
@@ -255,24 +255,24 @@ module Dry
255
255
  fn = callable.is_a?(String) ? FnContainer[callable] : callable
256
256
 
257
257
  case fn
258
- when Method
258
+ when ::Method
259
259
  yield "#{fn.receiver}.#{fn.name}"
260
- when Proc
260
+ when ::Proc
261
261
  path, line = fn.source_location
262
262
 
263
263
  if line&.zero?
264
264
  yield ".#{path}"
265
265
  elsif path
266
- yield "#{path.sub(Dir.pwd + '/', EMPTY_STRING)}:#{line}"
267
- elsif fn.lambda?
268
- yield '(lambda)'
266
+ yield "#{path.sub(Dir.pwd + "/", EMPTY_STRING)}:#{line}"
269
267
  else
270
- match = fn.to_s.match(/\A#<Proc:0x\h+\(&:(\w+)\)>\z/)
268
+ match = fn.to_s.match(/\A#<Proc:0x\h+\(&:(?<name>\w+)\)(:? \(lambda\))?>\z/)
271
269
 
272
270
  if match
273
- yield ".#{match[1]}"
271
+ yield ".#{match[:name]}"
272
+ elsif fn.lambda?
273
+ yield "(lambda)"
274
274
  else
275
- yield '(proc)'
275
+ yield "(proc)"
276
276
  end
277
277
  end
278
278
  else
@@ -288,9 +288,9 @@ module Dry
288
288
 
289
289
  def visit_options(options, meta = EMPTY_HASH)
290
290
  if options.empty? && meta.empty?
291
- yield ''
291
+ yield ""
292
292
  else
293
- opts = options.empty? ? '' : " options=#{options.inspect}"
293
+ opts = options.empty? ? "" : " options=#{options.inspect}"
294
294
 
295
295
  if meta.empty?
296
296
  yield opts
@@ -304,7 +304,7 @@ module Dry
304
304
  end
305
305
  end
306
306
 
307
- yield "#{opts} meta={#{values.join(', ')}}"
307
+ yield "#{opts} meta={#{values.join(", ")}}"
308
308
  end
309
309
  end
310
310
  end