dry-types 1.2.2 → 1.5.1

Sign up to get free protection for your applications and to get access to all the features.
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