Module: T
- Defined in:
- lib/types/_types.rb,
lib/types/boolean.rb,
lib/sorbet-runtime.rb,
lib/types/runtime_profiled.rb,
lib/types/compatibility_patches.rb
Overview
From the static system, T::Utils::RuntimeProfiled is T.untyped.
But from the runtime system, it’s a random class (specifically, a class that normal programs currently don’t have any instances of).
Thus, T::Utils::RuntimeProfiled can be used to introduce runtime-only type errors. This seems like a bad idea, but it’s not. It can be used to gather runtime type information from running code via a custom T::Configuration handler.
This process has only ever been used at Stripe, and is likely to have rough edges. If you’ve managed to find your way here and you’re curious to try it, please chat with us on Slack. There are no docs.
See also: the –suggest-runtime-profiled flag to sorbet.
Defined Under Namespace
Modules: AbstractUtils, Array, CFGExport, CompatibilityPatches, Configuration, Enumerable, Enumerator, Generic, Hash, Helpers, Private, Profile, Props, Range, Set, Sig, Types, Utils Classes: InexactStruct, InterfaceWrapper, Struct
Constant Summary collapse
- Boolean =
T::Boolean is a type alias helper for the common ‘T.any(TrueClass, FalseClass)`. Defined separately from _types.rb because it has a dependency on T::Types::Union.
T.type_alias(T.any(TrueClass, FalseClass))
Class Method Summary collapse
-
.absurd(value) ⇒ Object
A way to ask Sorbet to prove that a certain branch of control flow never happens.
-
.all(type_a, type_b, *types) ⇒ Object
T.all(<Type>, <Type>, …) – matches an object that has all of the types listed.
-
.any(type_a, type_b, *types) ⇒ Object
T.any(<Type>, <Type>, …) – matches any of the types listed.
-
.assert_type!(value, type, checked: true) ⇒ Object
Tells the typechecker to ensure that ‘value` is of type `type` (if not, the typechecker will fail).
-
.cast(value, type, checked: true) ⇒ Object
Tells the typechecker that ‘value` is of type `type`.
-
.class_of(klass) ⇒ Object
Matches any class that subclasses or includes the provided class or module.
-
.enum(values) ⇒ Object
Matches any of the listed values.
-
.let(value, type, checked: true) ⇒ Object
Tells the typechecker to declare a variable of type ‘type`.
-
.must(arg) ⇒ Object
A convenience method to ‘raise` when the argument is `nil` and return it otherwise.
-
.nilable(type) ⇒ Object
Shorthand for T.any(type, NilClass).
-
.noreturn ⇒ Object
Indicates a function never returns (e.g. “Kernel#raise”).
-
.proc ⇒ Object
Creates a proc type.
-
.reveal_type(value) ⇒ Object
A way to ask Sorbet to show what type it thinks an expression has.
-
.self_type ⇒ Object
Matches ‘self`:.
-
.type_alias(type) ⇒ Object
Constructs a type alias.
-
.type_parameter(name) ⇒ Object
References a type paramater which was previously defined with ‘type_parameters`.
-
.unsafe(value) ⇒ Object
For the static type checker, strips all type information from a value and returns the same value, but statically-typed as ‘T.untyped`.
-
.untyped ⇒ Object
Matches any object.
Class Method Details
.absurd(value) ⇒ Object
A way to ask Sorbet to prove that a certain branch of control flow never happens. Commonly used to assert that a case or if statement exhausts all possible cases.
201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/types/_types.rb', line 201 def self.absurd(value) msg = "Control flow reached T.absurd." case value when Kernel msg += " Got value: #{value}" end begin raise TypeError.new(msg) rescue TypeError => e # raise into rescue to ensure e.backtrace is populated T::Configuration.inline_type_error_handler(e) end end |
.all(type_a, type_b, *types) ⇒ Object
T.all(<Type>, <Type>, …) – matches an object that has all of the types listed
49 50 51 |
# File 'lib/types/_types.rb', line 49 def self.all(type_a, type_b, *types) T::Types::Intersection.new([type_a, type_b] + types) end |
.any(type_a, type_b, *types) ⇒ Object
T.any(<Type>, <Type>, …) – matches any of the types listed
28 29 30 |
# File 'lib/types/_types.rb', line 28 def self.any(type_a, type_b, *types) T::Types::Union.new([type_a, type_b] + types) end |
.assert_type!(value, type, checked: true) ⇒ Object
Tells the typechecker to ensure that ‘value` is of type `type` (if not, the typechecker will fail). Use this for debugging typechecking errors, or to ensure that type information is statically known and being checked appropriately. If `checked` is true, raises an exception at runtime if the value doesn’t match the type.
141 142 143 144 145 |
# File 'lib/types/_types.rb', line 141 def self.assert_type!(value, type, checked: true) return value unless checked Private::Casts.cast(value, type, cast_method: "T.assert_type!") end |
.cast(value, type, checked: true) ⇒ Object
Tells the typechecker that ‘value` is of type `type`. Use this to get additional checking after an expression that the typechecker is unable to analyze. If `checked` is true, raises an exception at runtime if the value doesn’t match the type.
Compared to ‘T.let`, `T.cast` is trusted by static system.
116 117 118 119 120 |
# File 'lib/types/_types.rb', line 116 def self.cast(value, type, checked: true) return value unless checked Private::Casts.cast(value, type, cast_method: "T.cast") end |
.class_of(klass) ⇒ Object
Matches any class that subclasses or includes the provided class or module
70 71 72 |
# File 'lib/types/_types.rb', line 70 def self.class_of(klass) T::Types::ClassOf.new(klass) end |
.enum(values) ⇒ Object
Matches any of the listed values
54 55 56 |
# File 'lib/types/_types.rb', line 54 def self.enum(values) T::Types::Enum.new(values) end |
.let(value, type, checked: true) ⇒ Object
Tells the typechecker to declare a variable of type ‘type`. Use like:
seconds = T.let(0.0, Float)
Compared to ‘T.cast`, `T.let` is checked by static system.
If ‘checked` is true, raises an exception at runtime if the value doesn’t match the type.
131 132 133 134 135 |
# File 'lib/types/_types.rb', line 131 def self.let(value, type, checked: true) return value unless checked Private::Casts.cast(value, type, cast_method: "T.let") end |
.must(arg) ⇒ Object
A convenience method to ‘raise` when the argument is `nil` and return it otherwise.
Intended to be used as:
needs_foo(T.must(maybe_gives_foo))
Equivalent to:
foo = maybe_gives_foo
raise "nil" if foo.nil?
needs_foo(foo)
Intended to be used to promise sorbet that a given nilable value happens to contain a non-nil value at this point.
sig T.nilable(A)).returns(A)
180 181 182 183 184 185 186 187 188 189 |
# File 'lib/types/_types.rb', line 180 def self.must(arg) return arg if arg return arg if arg == false begin raise TypeError.new("Passed `nil` into T.must") rescue TypeError => e # raise into rescue to ensure e.backtrace is populated T::Configuration.inline_type_error_handler(e) end end |
.nilable(type) ⇒ Object
Shorthand for T.any(type, NilClass)
33 34 35 |
# File 'lib/types/_types.rb', line 33 def self.nilable(type) T::Types::Union.new([type, NilClass]) end |
.noreturn ⇒ Object
Indicates a function never returns (e.g. “Kernel#raise”)
44 45 46 |
# File 'lib/types/_types.rb', line 44 def self.noreturn T::Types::NoReturn.new end |
.proc ⇒ Object
Creates a proc type
59 60 61 |
# File 'lib/types/_types.rb', line 59 def self.proc T::Private::Methods.start_proc end |
.reveal_type(value) ⇒ Object
A way to ask Sorbet to show what type it thinks an expression has. This can be useful for debugging and checking assumptions. In the runtime, merely returns the value passed in.
194 195 196 |
# File 'lib/types/_types.rb', line 194 def self.reveal_type(value) value end |
.self_type ⇒ Object
Matches ‘self`:
64 65 66 |
# File 'lib/types/_types.rb', line 64 def self.self_type T::Types::SelfType.new end |
.type_alias(type) ⇒ Object
Constructs a type alias. Used to create a short name for a larger type. In Ruby this is just equivalent to assignment, but this is needed for support by the static checker. Example usage:
NilableString = T.type_alias(T.nilable(String))
sig {params(arg: NilableString, default: String).returns(String)}
def or_else(arg, default)
arg || default
end
The name of the type alias is not preserved; Error messages will be printed with reference to the underlying type.
91 92 93 |
# File 'lib/types/_types.rb', line 91 def self.type_alias(type) T::Utils.coerce(type) end |
.type_parameter(name) ⇒ Object
107 108 109 |
# File 'lib/types/_types.rb', line 107 def self.type_parameter(name) T::Types::TypeParameter.new(name) end |
.unsafe(value) ⇒ Object
For the static type checker, strips all type information from a value and returns the same value, but statically-typed as ‘T.untyped`. Can be used to tell the static checker to “trust you” by discarding type information you know to be incorrect. Use with care! (This has no effect at runtime.)
We can’t actually write this sig because we ourselves are inside the ‘T::` module and doing this would create a bootstrapping cycle. However, we also don’t actually need to do so; An untyped identity method works just as well here.
sig T.untyped).returns(T.untyped)
159 160 161 |
# File 'lib/types/_types.rb', line 159 def self.unsafe(value) value end |