module T::Utils

typed: true

Public Class Methods

arity(method) click to toggle source

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
check_type_recursive!(value, type) click to toggle source

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
coerce(val) click to toggle source

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
lift_enum(enum) click to toggle source
# 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
methods_excluding_object(mod) click to toggle source

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
resolve_alias(type) click to toggle source

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
run_all_sig_blocks() click to toggle source

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
signature_for_instance_method(mod, method_name) click to toggle source

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
signature_for_method(method) click to toggle source

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
string_truncate_middle(str, start_len, end_len, ellipsis='...') click to toggle source

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
unwrap_nilable(type) click to toggle source

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
wrap_method_with_call_validation_if_needed(mod, method_sig, original_method) click to toggle source
# 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