Class: T::Types::TypedEnumerable
- Defined in:
- lib/types/types/typed_enumerable.rb
Overview
Note: All subclasses of Enumerable should add themselves to the ‘case` statement below in `describe_obj` in order to get better error messages.
Direct Known Subclasses
TypedArray, Untyped, TypedEnumerator, TypedEnumeratorChain, TypedEnumeratorLazy, TypedHash, TypedRange, TypedSet
Defined Under Namespace
Classes: Untyped
Instance Method Summary collapse
- #build_type ⇒ Object
-
#describe_obj(obj) ⇒ Object
overrides Base.
-
#initialize(type) ⇒ TypedEnumerable
constructor
A new instance of TypedEnumerable.
-
#name ⇒ Object
overrides Base.
-
#recursively_valid?(obj) ⇒ Boolean
overrides Base.
- #type ⇒ Object
- #underlying_class ⇒ Object
-
#valid?(obj) ⇒ Boolean
overrides Base.
Methods inherited from Base
#==, #error_message_for_obj, #error_message_for_obj_recursive, #hash, method_added, #subtype_of?, #to_s, #validate!
Constructor Details
#initialize(type) ⇒ TypedEnumerable
Returns a new instance of TypedEnumerable.
9 10 11 |
# File 'lib/types/types/typed_enumerable.rb', line 9 def initialize(type) @inner_type = type end |
Instance Method Details
#build_type ⇒ Object
17 18 19 20 |
# File 'lib/types/types/typed_enumerable.rb', line 17 def build_type type nil end |
#describe_obj(obj) ⇒ Object
overrides Base
108 109 110 111 |
# File 'lib/types/types/typed_enumerable.rb', line 108 def describe_obj(obj) return super unless obj.is_a?(Enumerable) type_from_instance(obj).name end |
#name ⇒ Object
overrides Base
27 28 29 |
# File 'lib/types/types/typed_enumerable.rb', line 27 def name "T::Enumerable[#{type.name}]" end |
#recursively_valid?(obj) ⇒ Boolean
overrides Base
37 38 39 40 41 42 43 44 45 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 |
# File 'lib/types/types/typed_enumerable.rb', line 37 def recursively_valid?(obj) return false unless obj.is_a?(Enumerable) case obj when Array begin it = 0 while it < obj.count return false unless type.recursively_valid?(obj[it]) it += 1 end true end when Hash type_ = self.type return false unless type_.is_a?(FixedArray) key_type, value_type = type_.types return false if key_type.nil? || value_type.nil? || type_.types.size > 2 obj.each_pair do |key, val| # Some objects (I'm looking at you Rack::Utils::HeaderHash) don't # iterate over a [key, value] array, so we can't just use the type.recursively_valid?(v) return false if !key_type.recursively_valid?(key) || !value_type.recursively_valid?(val) end true when Enumerator::Lazy # Enumerators can be unbounded: see `[:foo, :bar].cycle` true when Enumerator::Chain # Enumerators can be unbounded: see `[:foo, :bar].cycle` true when Enumerator # Enumerators can be unbounded: see `[:foo, :bar].cycle` true when Range # A nil beginning or a nil end does not provide any type information. That is, nil in a range represents # boundlessness, it does not express a type. For example `(nil...nil)` is not a T::Range[NilClass], its a range # of unknown types (T::Range[T.untyped]). # Similarly, `(nil...1)` is not a `T::Range[T.nilable(Integer)]`, it's a boundless range of Integer. (obj.begin.nil? || type.recursively_valid?(obj.begin)) && (obj.end.nil? || type.recursively_valid?(obj.end)) when Set obj.each do |item| return false unless type.recursively_valid?(item) end true else # We don't check the enumerable since it isn't guaranteed to be # rewindable (e.g. STDIN) and it may be expensive to enumerate # (e.g. an enumerator that makes an HTTP request)" true end end |
#type ⇒ Object
13 14 15 |
# File 'lib/types/types/typed_enumerable.rb', line 13 def type @type ||= T::Utils.coerce(@inner_type) end |
#underlying_class ⇒ Object
22 23 24 |
# File 'lib/types/types/typed_enumerable.rb', line 22 def Enumerable end |
#valid?(obj) ⇒ Boolean
overrides Base
32 33 34 |
# File 'lib/types/types/typed_enumerable.rb', line 32 def valid?(obj) obj.is_a?(Enumerable) end |