dry-types 0.14.1 → 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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +631 -134
  3. data/LICENSE +17 -17
  4. data/README.md +15 -13
  5. data/dry-types.gemspec +27 -30
  6. data/lib/dry/types/any.rb +32 -12
  7. data/lib/dry/types/array/constructor.rb +32 -0
  8. data/lib/dry/types/array/member.rb +75 -16
  9. data/lib/dry/types/array.rb +19 -6
  10. data/lib/dry/types/builder.rb +131 -15
  11. data/lib/dry/types/builder_methods.rb +49 -20
  12. data/lib/dry/types/coercions/json.rb +43 -7
  13. data/lib/dry/types/coercions/params.rb +118 -31
  14. data/lib/dry/types/coercions.rb +76 -22
  15. data/lib/dry/types/compat.rb +0 -2
  16. data/lib/dry/types/compiler.rb +56 -41
  17. data/lib/dry/types/constrained/coercible.rb +36 -6
  18. data/lib/dry/types/constrained.rb +81 -32
  19. data/lib/dry/types/constraints.rb +18 -4
  20. data/lib/dry/types/constructor/function.rb +216 -0
  21. data/lib/dry/types/constructor/wrapper.rb +94 -0
  22. data/lib/dry/types/constructor.rb +126 -56
  23. data/lib/dry/types/container.rb +7 -0
  24. data/lib/dry/types/core.rb +54 -21
  25. data/lib/dry/types/decorator.rb +38 -17
  26. data/lib/dry/types/default.rb +61 -16
  27. data/lib/dry/types/enum.rb +43 -20
  28. data/lib/dry/types/errors.rb +75 -9
  29. data/lib/dry/types/extensions/maybe.rb +74 -16
  30. data/lib/dry/types/extensions/monads.rb +29 -0
  31. data/lib/dry/types/extensions.rb +7 -1
  32. data/lib/dry/types/fn_container.rb +6 -1
  33. data/lib/dry/types/hash/constructor.rb +33 -0
  34. data/lib/dry/types/hash.rb +86 -67
  35. data/lib/dry/types/inflector.rb +3 -1
  36. data/lib/dry/types/json.rb +18 -16
  37. data/lib/dry/types/lax.rb +75 -0
  38. data/lib/dry/types/map.rb +76 -33
  39. data/lib/dry/types/meta.rb +51 -0
  40. data/lib/dry/types/module.rb +120 -0
  41. data/lib/dry/types/nominal.rb +210 -0
  42. data/lib/dry/types/options.rb +13 -26
  43. data/lib/dry/types/params.rb +39 -25
  44. data/lib/dry/types/predicate_inferrer.rb +238 -0
  45. data/lib/dry/types/predicate_registry.rb +34 -0
  46. data/lib/dry/types/primitive_inferrer.rb +97 -0
  47. data/lib/dry/types/printable.rb +16 -0
  48. data/lib/dry/types/printer.rb +315 -0
  49. data/lib/dry/types/result.rb +29 -3
  50. data/lib/dry/types/schema/key.rb +156 -0
  51. data/lib/dry/types/schema.rb +408 -0
  52. data/lib/dry/types/spec/types.rb +103 -33
  53. data/lib/dry/types/sum.rb +84 -35
  54. data/lib/dry/types/type.rb +49 -0
  55. data/lib/dry/types/version.rb +3 -1
  56. data/lib/dry/types.rb +156 -76
  57. data/lib/dry-types.rb +3 -1
  58. metadata +65 -78
  59. data/.gitignore +0 -10
  60. data/.rspec +0 -2
  61. data/.travis.yml +0 -27
  62. data/.yardopts +0 -5
  63. data/CONTRIBUTING.md +0 -29
  64. data/Gemfile +0 -24
  65. data/Rakefile +0 -20
  66. data/benchmarks/hash_schemas.rb +0 -51
  67. data/lib/dry/types/compat/form_types.rb +0 -27
  68. data/lib/dry/types/compat/int.rb +0 -14
  69. data/lib/dry/types/definition.rb +0 -113
  70. data/lib/dry/types/hash/schema.rb +0 -199
  71. data/lib/dry/types/hash/schema_builder.rb +0 -75
  72. data/lib/dry/types/safe.rb +0 -59
  73. data/log/.gitkeep +0 -0
@@ -1,9 +1,18 @@
1
- require 'dry/types/fn_container'
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/core/equalizer"
4
+ require "dry/types/fn_container"
5
+ require "dry/types/constructor/function"
6
+ require "dry/types/constructor/wrapper"
2
7
 
3
8
  module Dry
4
9
  module Types
5
- class Constructor < Definition
6
- include Dry::Equalizer(:type, :options, :meta)
10
+ # Constructor types apply a function to the input that is supposed to return
11
+ # a new value. Coercion is a common use case for constructor types.
12
+ #
13
+ # @api public
14
+ class Constructor < Nominal
15
+ include Dry::Equalizer(:type, :options, inspect: false, immutable: true)
7
16
 
8
17
  # @return [#call]
9
18
  attr_reader :fn
@@ -11,118 +20,179 @@ module Dry
11
20
  # @return [Type]
12
21
  attr_reader :type
13
22
 
14
- undef :constrained?
23
+ undef :constrained?, :meta, :optional?, :primitive, :default?, :name
15
24
 
16
25
  # @param [Builder, Object] input
17
26
  # @param [Hash] options
18
27
  # @param [#call, nil] block
28
+ #
29
+ # @api public
19
30
  def self.new(input, **options, &block)
20
- type = input.is_a?(Builder) ? input : Definition.new(input)
21
- super(type, **options, &block)
31
+ type = input.is_a?(Builder) ? input : Nominal.new(input)
32
+ super(type, **options, fn: Function[options.fetch(:fn, block)])
22
33
  end
23
34
 
24
- # @param [Type] type
35
+ # @param [Builder, Object] input
25
36
  # @param [Hash] options
26
37
  # @param [#call, nil] block
27
- def initialize(type, **options, &block)
28
- @type = type
29
- @fn = options.fetch(:fn, block)
30
-
31
- raise ArgumentError, 'Missing constructor block' if fn.nil?
38
+ #
39
+ # @api public
40
+ def self.[](type, fn:, **options)
41
+ function = Function[fn]
32
42
 
33
- super(type, **options, fn: fn)
43
+ if function.wrapper?
44
+ wrapper_type.new(type, fn: function, **options)
45
+ else
46
+ new(type, fn: function, **options)
47
+ end
34
48
  end
35
49
 
36
- # @return [Class]
37
- def primitive
38
- type.primitive
50
+ # @api private
51
+ def self.wrapper_type
52
+ @wrapper_type ||= begin
53
+ if self < Wrapper
54
+ self
55
+ else
56
+ const_set(:Wrapping, ::Class.new(self).include(Wrapper))
57
+ end
58
+ end
39
59
  end
40
60
 
41
- # @return [String]
42
- def name
43
- type.name
61
+ # Instantiate a new constructor type instance
62
+ #
63
+ # @param [Type] type
64
+ # @param [Function] fn
65
+ # @param [Hash] options
66
+ #
67
+ # @api private
68
+ def initialize(type, fn: nil, **options)
69
+ @type = type
70
+ @fn = fn
71
+
72
+ super(type, **options, fn: fn)
44
73
  end
45
74
 
46
- def default?
47
- type.default?
75
+ # @return [Object]
76
+ #
77
+ # @api private
78
+ def call_safe(input)
79
+ coerced = fn.(input) { |output = input| return yield(output) }
80
+ type.call_safe(coerced) { |output = coerced| yield(output) }
48
81
  end
49
82
 
50
- # @param [Object] input
51
83
  # @return [Object]
52
- def call(input)
53
- type[fn[input]]
84
+ #
85
+ # @api private
86
+ def call_unsafe(input)
87
+ type.call_unsafe(fn.(input))
54
88
  end
55
- alias_method :[], :call
56
89
 
57
90
  # @param [Object] input
58
91
  # @param [#call,nil] block
92
+ #
59
93
  # @return [Logic::Result, Types::Result]
60
94
  # @return [Object] if block given and try fails
95
+ #
96
+ # @api public
61
97
  def try(input, &block)
62
- type.try(fn[input], &block)
63
- rescue TypeError, ArgumentError => e
64
- failure(input, e.message)
98
+ value = fn.(input)
99
+ rescue CoercionError => e
100
+ failure = failure(input, e)
101
+ block_given? ? yield(failure) : failure
102
+ else
103
+ type.try(value, &block)
65
104
  end
66
105
 
106
+ # Build a new constructor by appending a block to the coercion function
107
+ #
67
108
  # @param [#call, nil] new_fn
68
109
  # @param [Hash] options
69
110
  # @param [#call, nil] block
111
+ #
70
112
  # @return [Constructor]
113
+ #
114
+ # @api public
71
115
  def constructor(new_fn = nil, **options, &block)
72
- left = new_fn || block
73
- right = fn
74
-
75
- with(options.merge(fn: -> input { left[right[input]] }))
76
- end
116
+ next_fn = Function[new_fn || block]
77
117
 
78
- # @param [Object] value
79
- # @return [Boolean]
80
- def valid?(value)
81
- constructed_value = fn[value]
82
- rescue NoMethodError, TypeError, ArgumentError
83
- false
84
- else
85
- type.valid?(constructed_value)
118
+ if next_fn.wrapper?
119
+ self.class.wrapper_type.new(with(**options), fn: next_fn)
120
+ else
121
+ with(**options, fn: fn >> next_fn)
122
+ end
86
123
  end
87
- alias_method :===, :valid?
124
+ alias_method :append, :constructor
125
+ alias_method :>>, :constructor
88
126
 
89
127
  # @return [Class]
128
+ #
129
+ # @api private
90
130
  def constrained_type
91
131
  Constrained::Coercible
92
132
  end
93
133
 
94
- # @api public
134
+ # @see Nominal#to_ast
95
135
  #
96
- # @see Definition#to_ast
136
+ # @api public
97
137
  def to_ast(meta: true)
98
- [:constructor, [type.to_ast(meta: meta),
99
- register_fn(fn),
100
- meta ? self.meta : EMPTY_HASH]]
138
+ [:constructor, [type.to_ast(meta: meta), fn.to_ast]]
101
139
  end
102
140
 
103
- private
141
+ # Build a new constructor by prepending a block to the coercion function
142
+ #
143
+ # @param [#call, nil] new_fn
144
+ # @param [Hash] options
145
+ # @param [#call, nil] block
146
+ #
147
+ # @return [Constructor]
148
+ #
149
+ # @api public
150
+ def prepend(new_fn = nil, **options, &block)
151
+ with(**options, fn: fn << (new_fn || block))
152
+ end
153
+ alias_method :<<, :prepend
154
+
155
+ # Build a lax type
156
+ #
157
+ # @return [Lax]
158
+ # @api public
159
+ def lax
160
+ Lax.new(constructor_type[type.lax, **options])
161
+ end
104
162
 
105
- def register_fn(fn)
106
- Dry::Types::FnContainer.register(fn)
163
+ # Wrap the type with a proc
164
+ #
165
+ # @return [Proc]
166
+ #
167
+ # @api public
168
+ def to_proc
169
+ proc { |value| self.(value) }
107
170
  end
108
171
 
172
+ private
173
+
109
174
  # @param [Symbol] meth
110
175
  # @param [Boolean] include_private
111
176
  # @return [Boolean]
177
+ #
178
+ # @api private
112
179
  def respond_to_missing?(meth, include_private = false)
113
180
  super || type.respond_to?(meth)
114
181
  end
115
182
 
116
183
  # Delegates missing methods to {#type}
117
- # @param [Symbol] meth
184
+ #
185
+ # @param [Symbol] method
118
186
  # @param [Array] args
119
187
  # @param [#call, nil] block
120
- def method_missing(meth, *args, &block)
121
- if type.respond_to?(meth)
122
- response = type.__send__(meth, *args, &block)
188
+ #
189
+ # @api private
190
+ def method_missing(method, *args, &block)
191
+ if type.respond_to?(method)
192
+ response = type.public_send(method, *args, &block)
123
193
 
124
- if response.kind_of?(Builder)
125
- self.class.new(response, options)
194
+ if response.is_a?(Type) && type.class.equal?(response.class)
195
+ response.constructor_type[response, **options]
126
196
  else
127
197
  response
128
198
  end
@@ -1,5 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/container"
4
+
1
5
  module Dry
2
6
  module Types
7
+ # Internal container for the built-in types
8
+ #
9
+ # @api private
3
10
  class Container
4
11
  include Dry::Container::Mixin
5
12
  end
@@ -1,8 +1,11 @@
1
- require 'dry/types/any'
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/types/any"
2
4
 
3
5
  module Dry
4
6
  module Types
5
- COERCIBLE = {
7
+ # Primitives with {Kernel} coercion methods
8
+ KERNEL_COERCIBLE = {
6
9
  string: String,
7
10
  integer: Integer,
8
11
  float: Float,
@@ -11,9 +14,19 @@ module Dry
11
14
  hash: ::Hash
12
15
  }.freeze
13
16
 
17
+ # Primitives with coercions through by convention `to_*` methods
18
+ METHOD_COERCIBLE = {
19
+ symbol: Symbol
20
+ }.freeze
21
+
22
+ # By convention methods to coerce {METHOD_COERCIBLE} primitives
23
+ METHOD_COERCIBLE_METHODS = {
24
+ symbol: :to_sym
25
+ }.freeze
26
+
27
+ # Primitives that are non-coercible
14
28
  NON_COERCIBLE = {
15
29
  nil: NilClass,
16
- symbol: Symbol,
17
30
  class: Class,
18
31
  true: TrueClass,
19
32
  false: FalseClass,
@@ -23,44 +36,64 @@ module Dry
23
36
  range: Range
24
37
  }.freeze
25
38
 
26
- ALL_PRIMITIVES = COERCIBLE.merge(NON_COERCIBLE).freeze
39
+ # All built-in primitives
40
+ ALL_PRIMITIVES = [KERNEL_COERCIBLE, METHOD_COERCIBLE, NON_COERCIBLE].reduce(&:merge).freeze
41
+
42
+ # All coercible types
43
+ COERCIBLE = KERNEL_COERCIBLE.merge(METHOD_COERCIBLE).freeze
27
44
 
45
+ # All built-in primitives except {NilClass}
28
46
  NON_NIL = ALL_PRIMITIVES.reject { |name, _| name == :nil }.freeze
29
47
 
30
- # Register built-in types that are non-coercible through kernel methods
48
+ # Register generic types for {ALL_PRIMITIVES}
31
49
  ALL_PRIMITIVES.each do |name, primitive|
32
- register(name.to_s, Definition[primitive].new(primitive))
50
+ type = Nominal[primitive].new(primitive)
51
+ register("nominal.#{name}", type)
33
52
  end
34
53
 
35
- # Register strict built-in types that are non-coercible through kernel methods
54
+ # Register strict types for {ALL_PRIMITIVES}
36
55
  ALL_PRIMITIVES.each do |name, primitive|
37
- register("strict.#{name}", self[name.to_s].constrained(type: primitive))
56
+ type = self["nominal.#{name}"].constrained(type: primitive)
57
+ register(name.to_s, type)
58
+ register("strict.#{name}", type)
59
+ end
60
+
61
+ # Register {KERNEL_COERCIBLE} types
62
+ KERNEL_COERCIBLE.each do |name, primitive|
63
+ register("coercible.#{name}", self["nominal.#{name}"].constructor(Kernel.method(primitive.name)))
38
64
  end
39
65
 
40
- # Register built-in primitive types with kernel coercion methods
41
- COERCIBLE.each do |name, primitive|
42
- register("coercible.#{name}", self[name.to_s].constructor(Kernel.method(primitive.name)))
66
+ # Register {METHOD_COERCIBLE} types
67
+ METHOD_COERCIBLE.each_key do |name|
68
+ register(
69
+ "coercible.#{name}", self["nominal.#{name}"].constructor(&METHOD_COERCIBLE_METHODS[name])
70
+ )
43
71
  end
44
72
 
45
- # Register non-coercible optional types
73
+ # Register optional strict {NON_NIL} types
46
74
  NON_NIL.each_key do |name|
47
- register("optional.strict.#{name}", self["strict.#{name}"].optional)
75
+ type = self[name.to_s].optional
76
+ register("optional.strict.#{name}", type)
77
+ register("optional.#{name}", type)
48
78
  end
49
79
 
50
- # Register coercible optional types
80
+ # Register optional {COERCIBLE} types
51
81
  COERCIBLE.each_key do |name|
52
82
  register("optional.coercible.#{name}", self["coercible.#{name}"].optional)
53
83
  end
54
84
 
55
- # Register :bool since it's common and not a built-in Ruby type :(
56
- register("bool", self["true"] | self["false"])
57
- register("strict.bool", self["strict.true"] | self["strict.false"])
85
+ # Register `:bool` since it's common and not a built-in Ruby type :(
86
+ register("nominal.bool", self["nominal.true"] | self["nominal.false"])
87
+ bool = self["strict.true"] | self["strict.false"]
88
+ register("strict.bool", bool)
89
+ register("bool", bool)
58
90
 
59
91
  register("any", Any)
60
- register("object", self['any'])
92
+ register("nominal.any", Any)
93
+ register("strict.any", Any)
61
94
  end
62
95
  end
63
96
 
64
- require 'dry/types/coercions'
65
- require 'dry/types/params'
66
- require 'dry/types/json'
97
+ require "dry/types/coercions"
98
+ require "dry/types/params"
99
+ require "dry/types/json"
@@ -1,7 +1,12 @@
1
- require 'dry/types/options'
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/types/options"
2
4
 
3
5
  module Dry
4
6
  module Types
7
+ # Common API for types
8
+ #
9
+ # @api public
5
10
  module Decorator
6
11
  include Options
7
12
 
@@ -9,63 +14,76 @@ module Dry
9
14
  attr_reader :type
10
15
 
11
16
  # @param [Type] type
12
- def initialize(type, *)
17
+ def initialize(type, *, **)
13
18
  super
14
19
  @type = type
15
20
  end
16
21
 
17
22
  # @param [Object] input
18
23
  # @param [#call, nil] block
24
+ #
19
25
  # @return [Result,Logic::Result]
20
26
  # @return [Object] if block given and try fails
27
+ #
28
+ # @api public
21
29
  def try(input, &block)
22
30
  type.try(input, &block)
23
31
  end
24
32
 
25
- # @param [Object] value
26
- # @return [Boolean]
27
- def valid?(value)
28
- type.valid?(value)
29
- end
30
- alias_method :===, :valid?
31
-
32
33
  # @return [Boolean]
34
+ #
35
+ # @api public
33
36
  def default?
34
37
  type.default?
35
38
  end
36
39
 
37
40
  # @return [Boolean]
41
+ #
42
+ # @api public
38
43
  def constrained?
39
44
  type.constrained?
40
45
  end
41
46
 
42
- # @return [Sum]
43
- def optional
44
- Types['strict.nil'] | self
45
- end
46
-
47
47
  # @param [Symbol] meth
48
48
  # @param [Boolean] include_private
49
+ #
49
50
  # @return [Boolean]
51
+ #
52
+ # @api public
50
53
  def respond_to_missing?(meth, include_private = false)
51
54
  super || type.respond_to?(meth)
52
55
  end
53
56
 
57
+ # Wrap the type with a proc
58
+ #
59
+ # @return [Proc]
60
+ #
61
+ # @api public
62
+ def to_proc
63
+ proc { |value| self.(value) }
64
+ end
65
+
54
66
  private
55
67
 
56
68
  # @param [Object] response
69
+ #
57
70
  # @return [Boolean]
71
+ #
72
+ # @api private
58
73
  def decorate?(response)
59
- response.kind_of?(type.class)
74
+ response.is_a?(type.class)
60
75
  end
61
76
 
62
77
  # Delegates missing methods to {#type}
78
+ #
63
79
  # @param [Symbol] meth
64
80
  # @param [Array] args
65
81
  # @param [#call, nil] block
82
+ #
83
+ # @api private
66
84
  def method_missing(meth, *args, &block)
67
85
  if type.respond_to?(meth)
68
- response = type.__send__(meth, *args, &block)
86
+ response = type.public_send(meth, *args, &block)
69
87
 
70
88
  if decorate?(response)
71
89
  __new__(response)
@@ -76,10 +94,13 @@ module Dry
76
94
  super
77
95
  end
78
96
  end
97
+ ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
79
98
 
80
99
  # Replace underlying type
100
+ #
101
+ # @api private
81
102
  def __new__(type)
82
- self.class.new(type, options)
103
+ self.class.new(type, *@__args__.drop(1), **@options)
83
104
  end
84
105
  end
85
106
  end
@@ -1,30 +1,46 @@
1
- require 'dry/types/decorator'
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/core/equalizer"
4
+ require "dry/types/decorator"
2
5
 
3
6
  module Dry
4
7
  module Types
8
+ # Default types are useful when a missing value should be replaced by a default one
9
+ #
10
+ # @api public
5
11
  class Default
6
- include Type
7
- include Dry::Equalizer(:type, :options, :value)
8
- include Decorator
9
- include Builder
10
-
12
+ # @api private
11
13
  class Callable < Default
12
- include Dry::Equalizer(:type, :options)
14
+ include Dry::Equalizer(:type, inspect: false, immutable: true)
13
15
 
14
16
  # Evaluates given callable
15
17
  # @return [Object]
16
18
  def evaluate
17
19
  value.call(type)
18
20
  end
21
+
22
+ # @return [true]
23
+ def callable?
24
+ true
25
+ end
19
26
  end
20
27
 
28
+ include Type
29
+ include Decorator
30
+ include Builder
31
+ include Printable
32
+ include Dry::Equalizer(:type, :value, inspect: false, immutable: true)
33
+
21
34
  # @return [Object]
22
35
  attr_reader :value
23
36
 
24
37
  alias_method :evaluate, :value
25
38
 
26
39
  # @param [Object, #call] value
40
+ #
27
41
  # @return [Class] {Default} or {Default::Callable}
42
+ #
43
+ # @api private
28
44
  def self.[](value)
29
45
  if value.respond_to?(:call)
30
46
  Callable
@@ -35,49 +51,78 @@ module Dry
35
51
 
36
52
  # @param [Type] type
37
53
  # @param [Object] value
54
+ #
55
+ # @api private
38
56
  def initialize(type, value, **options)
39
57
  super
40
58
  @value = value
41
59
  end
42
60
 
61
+ # Build a constrained type
62
+ #
43
63
  # @param [Array] args see {Dry::Types::Builder#constrained}
64
+ #
44
65
  # @return [Default]
66
+ #
67
+ # @api public
45
68
  def constrained(*args)
46
69
  type.constrained(*args).default(value)
47
70
  end
48
71
 
49
72
  # @return [true]
73
+ #
74
+ # @api public
50
75
  def default?
51
76
  true
52
77
  end
53
78
 
54
79
  # @param [Object] input
80
+ #
55
81
  # @return [Result::Success]
82
+ #
83
+ # @api public
56
84
  def try(input)
57
85
  success(call(input))
58
86
  end
59
87
 
88
+ # @return [Boolean]
89
+ #
90
+ # @api public
60
91
  def valid?(value = Undefined)
61
- value.equal?(Undefined) || super
92
+ Undefined.equal?(value) || super
62
93
  end
63
94
 
64
95
  # @param [Object] input
96
+ #
65
97
  # @return [Object] value passed through {#type} or {#default} value
66
- def call(input = Undefined)
98
+ #
99
+ # @api private
100
+ def call_unsafe(input = Undefined)
67
101
  if input.equal?(Undefined)
68
102
  evaluate
69
103
  else
70
- output = type[input]
71
- output.nil? ? evaluate : output
104
+ Undefined.default(type.call_unsafe(input)) { evaluate }
72
105
  end
73
106
  end
74
- alias_method :[], :call
75
107
 
76
- private
108
+ # @param [Object] input
109
+ #
110
+ # @return [Object] value passed through {#type} or {#default} value
111
+ #
112
+ # @api private
113
+ def call_safe(input = Undefined, &block)
114
+ if input.equal?(Undefined)
115
+ evaluate
116
+ else
117
+ Undefined.default(type.call_safe(input, &block)) { evaluate }
118
+ end
119
+ end
77
120
 
78
- # Replace underlying type
79
- def __new__(type)
80
- self.class.new(type, value, options)
121
+ # @return [false]
122
+ #
123
+ # @api private
124
+ def callable?
125
+ false
81
126
  end
82
127
  end
83
128
  end