module T::Utils
typed: true
Public Class Methods
Returns the arity of a method, unwrapping the sig if needed
# File lib/types/utils.rb, line 103 def self.arity(method) arity = method.arity return arity if arity != -1 || method.is_a?(Proc) sig = T::Private::Methods.signature_for_method(method) sig ? sig.method.arity : arity end
Dynamically confirm that `value` is recursively a valid value of type `type`, including recursively through collections. Note that in some cases this runtime check can be very expensive, especially with large collections of objects.
# File lib/types/utils.rb, line 34 def self.check_type_recursive!(value, type) T::Private::Casts.cast_recursive(value, type, cast_method: "T.check_type_recursive!") end
Used to convert from a type specification to a `T::Types::Base`.
# File lib/types/utils.rb, line 6 def self.coerce(val) if val.is_a?(T::Private::Types::TypeAlias) val.aliased_type elsif val.is_a?(T::Types::Base) val elsif val.is_a?(Module) T::Types::Simple::Private::Pool.type_for_module(val) elsif val.is_a?(::Array) T::Types::FixedArray.new(val) elsif val.is_a?(::Hash) T::Types::FixedHash.new(val) elsif val.is_a?(T::Private::Methods::DeclBuilder) T::Private::Methods.finalize_proc(val.decl) elsif val.is_a?(::T::Enum) T::Types::TEnum.new(val) elsif val.is_a?(::String) raise "Invalid String literal for type constraint. Must be an #{T::Types::Base}, a " \ "class/module, or an array. Got a String with value `#{val}`." else raise "Invalid value for type constraint. Must be an #{T::Types::Base}, a " \ "class/module, or an array. Got a `#{val.class}`." end end
# File lib/types/utils.rb, line 146 def self.lift_enum(enum) unless enum.is_a?(T::Types::Enum) raise ArgumentError.new("#{enum.inspect} is not a T.enum") end classes = enum.values.map(&:class).uniq if classes.empty? T.untyped elsif classes.length > 1 T::Types::Union.new(classes) else T::Types::Simple::Private::Pool.type_for_module(classes.first) end end
Returns the set of all methods (public, protected, private) defined on a module or its ancestors, excluding Object and its ancestors. Overrides of methods from Object (and its ancestors) are included.
# File lib/types/utils.rb, line 41 def self.methods_excluding_object(mod) # We can't just do mod.instance_methods - Object.instance_methods, because that would leave out # any methods from Object that are overridden in mod. mod.ancestors.flat_map do |ancestor| # equivalent to checking Object.ancestors.include?(ancestor) next [] if Object <= ancestor ancestor.instance_methods(false) + ancestor.private_instance_methods(false) end.uniq end
Return the underlying type for a type alias. Otherwise returns type.
# File lib/types/utils.rb, line 75 def self.resolve_alias(type) case type when T::Private::Types::TypeAlias type.aliased_type else type end end
Unwraps all the sigs.
# File lib/types/utils.rb, line 70 def self.run_all_sig_blocks T::Private::Methods.run_all_sig_blocks end
Returns the signature for the instance method on the supplied module, or nil if it's not found or not typed.
@example T::Utils.signature_for_instance_method
(MyClass, :my_method)
# File lib/types/utils.rb, line 61 def self.signature_for_instance_method(mod, method_name) T::Private::Methods.signature_for_method(mod.instance_method(method_name)) end
Returns the signature for the `UnboundMethod`, or nil if it's not sig'd
@example T::Utils.signature_for_method
(x.method(:foo))
# File lib/types/utils.rb, line 54 def self.signature_for_method(method) T::Private::Methods.signature_for_method(method) end
Elide the middle of a string as needed and replace it with an ellipsis. Keep the given number of characters at the start and end of the string.
This method operates on string length, not byte length.
If the string is shorter than the requested truncation length, return it without adding an ellipsis. This method may return a longer string than the original if the characters removed are shorter than the ellipsis.
@param [String] str
@param [Fixnum] start_len The length of string before the ellipsis @param [Fixnum] end_len The length of string after the ellipsis
@param [String] ellipsis The string to add in place of the elided text
@return [String]
# File lib/types/utils.rb, line 128 def self.string_truncate_middle(str, start_len, end_len, ellipsis='...') return unless str raise ArgumentError.new('must provide start_len') unless start_len raise ArgumentError.new('must provide end_len') unless end_len raise ArgumentError.new('start_len must be >= 0') if start_len < 0 raise ArgumentError.new('end_len must be >= 0') if end_len < 0 str = str.to_s return str if str.length <= start_len + end_len start_part = str[0...start_len - ellipsis.length] end_part = end_len == 0 ? '' : str[-end_len..-1] "#{start_part}#{ellipsis}#{end_part}" end
Give a type which is a subclass of T::Types::Base
, determines if the type is a simple nilable type (union of NilClass and something else). If so, returns the T::Types::Base
of the something else. Otherwise, returns nil.
# File lib/types/utils.rb, line 86 def self.unwrap_nilable(type) case type when T::Types::Union non_nil_types = type.types.reject {|t| t == Nilable::NIL_TYPE} return nil if type.types.length == non_nil_types.length case non_nil_types.length when 0 then nil when 1 then non_nil_types.first else T::Types::Union::Private::Pool.union_of_types(non_nil_types[0], non_nil_types[1], non_nil_types[2..-1]) end else nil end end
# File lib/types/utils.rb, line 65 def self.wrap_method_with_call_validation_if_needed(mod, method_sig, original_method) T::Private::Methods::CallValidation.wrap_method_if_needed(mod, method_sig, original_method) end