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(EMPTY_ARRAY)

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from PAnyType

#==, #assignable?, #callable?, #kind_of_callable?, #simple_name, #to_alias_expanded_s, #to_s

Constructor Details

#initialize(types, size_type = nil) ⇒ PTupleType

Returns a new instance of PTupleType.



1363
1364
1365
1366
# File 'lib/puppet/pops/types/types.rb', line 1363

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



1320
1321
1322
# File 'lib/puppet/pops/types/types.rb', line 1320

def size_type
  @size_type
end

#typesObject (readonly)



1322
1323
1324
# File 'lib/puppet/pops/types/types.rb', line 1322

def types
  @types
end

Instance Method Details

#accept(visitor, guard) ⇒ Object



1324
1325
1326
1327
1328
# File 'lib/puppet/pops/types/types.rb', line 1324

def accept(visitor, guard)
  super
  @size_type.accept(visitor, guard) unless @size_type.nil?
  @types.each { |elem| elem.accept(visitor, guard) }
end

#callable_args?(callable_t, guard) ⇒ 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)


1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
# File 'lib/puppet/pops/types/types.rb', line 1331

def callable_args?(callable_t, guard)
  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?(true, guard)
    # 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, guard)

    # 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), guard)

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

  # Check that tuple is assignable and that the block (if declared) is optional
  params_tuple.assignable?(self, guard) && (param_block_t.nil? || param_block_t.assignable?(PUndefType::DEFAULT, guard))
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



1370
1371
1372
1373
1374
1375
1376
# File 'lib/puppet/pops/types/types.rb', line 1370

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

#eql?(o) ⇒ Boolean

Returns:

  • (Boolean)


1443
1444
1445
# File 'lib/puppet/pops/types/types.rb', line 1443

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

#generalizeObject



1378
1379
1380
1381
1382
1383
1384
# File 'lib/puppet/pops/types/types.rb', line 1378

def generalize
  if self == DEFAULT
    DEFAULT
  else
    alter_type_array(@types, :generalize) { |altered_types| PTupleType.new(altered_types, @size_type) }
  end
end

#hashObject



1439
1440
1441
# File 'lib/puppet/pops/types/types.rb', line 1439

def hash
  @size_type.hash ^ @types.hash
end

#instance?(o) ⇒ Boolean

Returns:

  • (Boolean)


1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
# File 'lib/puppet/pops/types/types.rb', line 1394

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

#iterable?(guard = nil) ⇒ Boolean

Returns:

  • (Boolean)


1406
1407
1408
# File 'lib/puppet/pops/types/types.rb', line 1406

def iterable?(guard = nil)
  true
end

#iterable_type(guard = nil) ⇒ Object



1410
1411
1412
# File 'lib/puppet/pops/types/types.rb', line 1410

def iterable_type(guard = nil)
  PIterableType.new(TypeCalculator.singleton.unwrap_single_variant(PVariantType.new(types)))
end

#normalize(guard = nil) ⇒ Object



1386
1387
1388
1389
1390
1391
1392
# File 'lib/puppet/pops/types/types.rb', line 1386

def normalize(guard = nil)
  if self == DEFAULT
    DEFAULT
  else
    alter_type_array(@types, :normalize, guard) { |altered_types| PTupleType.new(altered_types, @size_type) }
  end
end

#repeat_last_rangeObject

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



1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
# File 'lib/puppet/pops/types/types.rb', line 1427

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



1415
1416
1417
1418
1419
1420
1421
1422
# File 'lib/puppet/pops/types/types.rb', line 1415

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