Class: T::Types::Base
- Inherits:
-
Object
- Object
- T::Types::Base
- Defined in:
- lib/types/types/base.rb
Direct Known Subclasses
Private::Types::NotTyped, Private::Types::StringHolder, Private::Types::TypeAlias, Private::Types::Void, AttachedClassType, ClassOf, Enum, FixedArray, FixedHash, Intersection, NoReturn, Proc, SelfType, Simple, TEnum, TypeParameter, TypeVariable, TypedEnumerable, Union, Untyped
Class Method Summary collapse
Instance Method Summary collapse
-
#==(other) ⇒ Object
(also: #eql?)
Type equivalence, defined by serializing the type to a string (with ‘#name`) and comparing the resulting strings for equality.
- #describe_obj(obj) ⇒ Object
- #error_message_for_obj(obj) ⇒ Object
- #error_message_for_obj_recursive(obj) ⇒ Object
-
#hash ⇒ Object
Equality methods (necessary for deduping types with ‘uniq`).
-
#name ⇒ Object
Equality is based on name, so be sure the name reflects all relevant state when implementing.
-
#recursively_valid?(obj) ⇒ Boolean
this will be redefined in certain subclasses.
-
#subtype_of?(t2) ⇒ Boolean
Mirrors ruby_typer::core::Types::isSubType See git.corp.stripe.com/stripe-internal/ruby-typer/blob/9fc8ed998c04ac0b96592ae6bb3493b8a925c5c1/core/types/subtyping.cc#L912-L950.
- #to_s ⇒ Object
- #valid?(obj) ⇒ Boolean
- #validate!(obj) ⇒ Object
Class Method Details
.method_added(method_name) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 |
# File 'lib/types/types/base.rb', line 6 def self.method_added(method_name) super(method_name) # What is now `subtype_of_single?` used to be named `subtype_of?`. Make sure people don't # override the wrong thing. # # NB: Outside of T::Types, we would enforce this by using `sig` and not declaring the method # as overridable, but doing so here would result in a dependency cycle. if method_name == :subtype_of? && self != T::Types::Base raise "`subtype_of?` should not be overridden. You probably want to override " \ "`subtype_of_single?` instead." end end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
Type equivalence, defined by serializing the type to a string (with ‘#name`) and comparing the resulting strings for equality.
171 172 173 174 175 176 177 178 |
# File 'lib/types/types/base.rb', line 171 def ==(other) case other when T::Types::Base other.name == self.name else false end end |
#describe_obj(obj) ⇒ Object
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/types/types/base.rb', line 116 def describe_obj(obj) # Would be redundant to print class and value in these common cases. case obj when nil, true, false return "type #{obj.class}" end # In rare cases, obj.inspect may fail, or be undefined, so rescue. begin # Default inspect behavior of, eg; `#<Object:0x0...>` is ugly; just print the hash instead, which is more concise/readable. if obj.method(:inspect).owner == Kernel "type #{obj.class} with hash #{obj.hash}" elsif T::Configuration.include_value_in_type_errors? "type #{obj.class} with value #{T::Utils.string_truncate_middle(obj.inspect, 30, 30)}" else "type #{obj.class}" end rescue StandardError, SystemStackError "type #{obj.class} with unprintable value" end end |
#error_message_for_obj(obj) ⇒ Object
138 139 140 141 142 143 144 |
# File 'lib/types/types/base.rb', line 138 def (obj) if valid?(obj) nil else (obj) end end |
#error_message_for_obj_recursive(obj) ⇒ Object
146 147 148 149 150 151 152 |
# File 'lib/types/types/base.rb', line 146 def (obj) if recursively_valid?(obj) nil else (obj) end end |
#hash ⇒ Object
Equality methods (necessary for deduping types with ‘uniq`)
165 166 167 |
# File 'lib/types/types/base.rb', line 165 def hash name.hash end |
#name ⇒ Object
Equality is based on name, so be sure the name reflects all relevant state when implementing.
37 38 39 |
# File 'lib/types/types/base.rb', line 37 def name raise NotImplementedError end |
#recursively_valid?(obj) ⇒ Boolean
this will be redefined in certain subclasses
20 21 22 |
# File 'lib/types/types/base.rb', line 20 def recursively_valid?(obj) valid?(obj) end |
#subtype_of?(t2) ⇒ Boolean
Mirrors ruby_typer::core::Types::isSubType See git.corp.stripe.com/stripe-internal/ruby-typer/blob/9fc8ed998c04ac0b96592ae6bb3493b8a925c5c1/core/types/subtyping.cc#L912-L950
This method cannot be overridden (see ‘method_added` above). Subclasses only need to implement `subtype_of_single?`).
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/types/types/base.rb', line 46 def subtype_of?(t2) t1 = self if t2.is_a?(T::Private::Types::TypeAlias) t2 = t2.aliased_type end if t1.is_a?(T::Private::Types::TypeAlias) return t1.aliased_type.subtype_of?(t2) end if t1.is_a?(T::Types::TypeVariable) || t2.is_a?(T::Types::TypeVariable) # Generics are erased at runtime. Let's treat them like `T.untyped` for # the purpose of things like override checking. return true end # pairs to cover: 1 (_, _) # 2 (_, And) # 3 (_, Or) # 4 (And, _) # 5 (And, And) # 6 (And, Or) # 7 (Or, _) # 8 (Or, And) # 9 (Or, Or) # Note: order of cases here matters! if t1.is_a?(T::Types::Union) # 7, 8, 9 # this will be incorrect if/when we have Type members return t1.types.all? {|t1_member| t1_member.subtype_of?(t2)} end if t2.is_a?(T::Types::Intersection) # 2, 5 # this will be incorrect if/when we have Type members return t2.types.all? {|t2_member| t1.subtype_of?(t2_member)} end if t2.is_a?(T::Types::Union) if t1.is_a?(T::Types::Intersection) # 6 # dropping either of parts eagerly make subtype test be too strict. # we have to try both cases, when we normally try only one return t2.types.any? {|t2_member| t1.subtype_of?(t2_member)} || t1.types.any? {|t1_member| t1_member.subtype_of?(t2)} end return t2.types.any? {|t2_member| t1.subtype_of?(t2_member)} # 3 end if t1.is_a?(T::Types::Intersection) # 4 # this will be incorrect if/when we have Type members return t1.types.any? {|t1_member| t1_member.subtype_of?(t2)} end # 1; Start with some special cases if t1.is_a?(T::Private::Types::Void) return t2.is_a?(T::Private::Types::Void) end if t1.is_a?(T::Types::Untyped) || t2.is_a?(T::Types::Untyped) return true end # Rest of (1) subtype_of_single?(t2) end |
#to_s ⇒ Object
112 113 114 |
# File 'lib/types/types/base.rb', line 112 def to_s name end |
#valid?(obj) ⇒ Boolean
24 25 26 |
# File 'lib/types/types/base.rb', line 24 def valid?(obj) raise NotImplementedError end |
#validate!(obj) ⇒ Object
158 159 160 161 |
# File 'lib/types/types/base.rb', line 158 def validate!(obj) err = (obj) raise TypeError.new(err) if err end |