Class: Puppet::Pops::Types::PTupleType

Inherits:
PAnyType show all
Includes:
Enumerable
Defined in:
lib/puppet/pops/types/types.rb

Constant Summary collapse

DATA =
PTupleType.new([PDataType::DEFAULT], PCollectionType::DEFAULT_SIZE)
DEFAULT =
PTupleType.new([])

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from PAnyType

#assignable?, #callable?, #enumerable?, #kind_of_callable?, #simple_name, #to_s

Methods included from Visitable

#accept

Constructor Details

#initialize(types, size_type = nil) ⇒ PTupleType

Returns a new instance of PTupleType.



961
962
963
964
# File 'lib/puppet/pops/types/types.rb', line 961

def initialize(types, size_type = nil)
  @types = types
  @size_type = size_type.nil? ? nil : size_type.to_size
end

Instance Attribute Details

#size_typeObject (readonly)

If set, describes min and max required of the given types - if max > size of types, the last type entry repeats



924
925
926
# File 'lib/puppet/pops/types/types.rb', line 924

def size_type
  @size_type
end

#typesObject (readonly)



926
927
928
# File 'lib/puppet/pops/types/types.rb', line 926

def types
  @types
end

Instance Method Details

#==(o) ⇒ Object



1021
1022
1023
# File 'lib/puppet/pops/types/types.rb', line 1021

def ==(o)
  self.class == o.class && @types == o.types && @size_type == o.size_type
end

#callable_args?(callable_t) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
# File 'lib/puppet/pops/types/types.rb', line 929

def callable_args?(callable_t)
  unless size_type.nil?
    raise ArgumentError, 'Callable tuple may not have a size constraint when used as args'
  end

  params_tuple = callable_t.param_types
  param_block_t = callable_t.block_type
  arg_types = @types
  arg_block_t = arg_types.last
  if arg_block_t.kind_of_callable?
    # Can't pass a block to a callable that doesn't accept one
    return false if param_block_t.nil?

    # Check that the block is of the right tyṕe
    return false unless param_block_t.assignable?(arg_block_t)

    # Check other arguments
    arg_count = arg_types.size - 1
    params_size_t = params_tuple.size_type || PIntegerType.new(*params_tuple.size_range)
    return false unless params_size_t.assignable?(PIntegerType.new(arg_count, arg_count))

    ctypes = params_tuple.types
    arg_count.times do |index|
      return false unless (ctypes[index] || ctypes[-1]).assignable?(arg_types[index])
    end
    return true
  end

  # Check that tuple is assignable and that the block (if declared) is optional
  params_tuple.assignable?(self) && (param_block_t.nil? || param_block_t.assignable?(PUndefType::DEFAULT))
end

#eachObject

Returns Enumerator for the types if no block is given, otherwise, calls the given block with each of the types in this tuple



968
969
970
971
972
973
974
# File 'lib/puppet/pops/types/types.rb', line 968

def each
  if block_given?
    types.each { |x| yield x }
  else
    types.to_enum
  end
end

#generalizeObject



976
977
978
# File 'lib/puppet/pops/types/types.rb', line 976

def generalize
  self == DEFAULT ? self : PTupleType.new(@types.map {|t| t.generalize })
end

#hashObject



1017
1018
1019
# File 'lib/puppet/pops/types/types.rb', line 1017

def hash
  @size_type.hash * 31 + @types.hash
end

#instance?(o) ⇒ Boolean

Returns:

  • (Boolean)


980
981
982
983
984
985
986
987
988
989
990
# File 'lib/puppet/pops/types/types.rb', line 980

def instance?(o)
  return false unless o.is_a?(Array)
  # compute the tuple's min/max size, and check if that size matches
  size_t = size_type || PIntegerType.new(*size_range)

  return false unless size_t.instance?(o.size)
  o.each_with_index do |element, index|
    return false unless (types[index] || types[-1]).instance?(element)
  end
  true
end

#repeat_last_rangeObject

Returns the number of accepted occurrences [min, max] of the last type in the tuple The defaults is [1,1]



1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
# File 'lib/puppet/pops/types/types.rb', line 1005

def repeat_last_range
  if @size_type.nil?
    return [1, 1]
  end
  types_size = @types.size
  from, to = @size_type.range
  min = from - (types_size-1)
  min = min <= 0 ? 0 : min
  max = to - (types_size-1)
  [min, max]
end

#size_rangeObject

Returns the number of elements accepted [min, max] in the tuple



993
994
995
996
997
998
999
1000
# File 'lib/puppet/pops/types/types.rb', line 993

def size_range
  if @size_type.nil?
    types_size = @types.size
    [types_size, types_size]
  else
    @size_type.range
  end
end