class Puppet::Pops::Types::TypeFormatter
String
Creates a string representation of a type.
@api public
Constants
- COMMA_SEP
- HASH_ENTRY_OP
- NAME_SEGMENT_SEPARATOR
- STARTS_WITH_ASCII_CAPITAL
Public Class Methods
# File lib/puppet/pops/types/type_formatter.rb 25 def initialize 26 @string_visitor = Visitor.new(nil, 'string', 0, 0) 27 end
Produces a String representation of the given type. @param t [PAnyType] the type to produce a string form @return [String] the type in string form
@api public
# File lib/puppet/pops/types/type_formatter.rb 21 def self.string(t) 22 singleton.string(t) 23 end
Public Instance Methods
Produces a string representing the type where type aliases have been expanded @api public
# File lib/puppet/pops/types/type_formatter.rb 123 def alias_expanded_string(t) 124 @expanded = true 125 begin 126 string(t) 127 ensure 128 @expanded = false 129 end 130 end
# File lib/puppet/pops/types/type_formatter.rb 296 def append_callable_params(t) 297 # translate to string, and skip Unit types 298 append_strings(t.param_types.types.reject {|t2| t2.class == PUnitType }, true) 299 300 if t.param_types.types.empty? 301 append_strings([0, 0], true) 302 else 303 append_elements(range_array_part(t.param_types.size_type), true) 304 end 305 306 # Add block T last (after min, max) if present) 307 # 308 append_strings([t.block_type], true) unless t.block_type.nil? 309 chomp_list 310 end
# File lib/puppet/pops/types/type_formatter.rb 101 def append_default 102 @bld << 'default' 103 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 73 def append_indented_string(t, indent = 0, indent_width = 2, skip_initial_indent = false) 74 save_indent = @indent 75 save_indent_width = @indent_width 76 @indent = indent 77 @indent_width = indent_width 78 begin 79 (@indent * @indent_width).times { @bld << ' ' } unless skip_initial_indent 80 append_string(t) 81 @bld << "\n" 82 ensure 83 @indent = save_indent 84 @indent_width = save_indent_width 85 end 86 end
# File lib/puppet/pops/types/type_formatter.rb 105 def append_string(t) 106 if @ruby && t.is_a?(PAnyType) 107 @ruby = false 108 begin 109 @bld << @ref_ctor << '(' 110 @string_visitor.visit_this_0(self, TypeFormatter.new.string(t)) 111 @bld << ')' 112 ensure 113 @ruby = true 114 end 115 else 116 @string_visitor.visit_this_0(self, t) 117 end 118 end
Capitalizes each segment in a name separated with the {NAME_SEPARATOR} conditionally. The name will not be subject to capitalization if it already starts with a capital letter. This to avoid that existing camel casing is lost.
@param qualified_name [String] the name to capitalize @return [String] the capitalized name
@api private
# File lib/puppet/pops/types/type_formatter.rb 649 def capitalize_segments(qualified_name) 650 if !qualified_name.is_a?(String) || qualified_name =~ STARTS_WITH_ASCII_CAPITAL 651 qualified_name 652 else 653 segments = qualified_name.split(NAME_SEGMENT_SEPARATOR) 654 if segments.size == 1 655 qualified_name.capitalize 656 else 657 segments.each(&:capitalize!) 658 segments.join(NAME_SEGMENT_SEPARATOR) 659 end 660 end 661 end
Produces a debug string representing the type (possibly with more information that the regular string format) @api public
# File lib/puppet/pops/types/type_formatter.rb 135 def debug_string(t) 136 @debug = true 137 begin 138 string(t) 139 ensure 140 @debug = false 141 end 142 end
# File lib/puppet/pops/types/type_formatter.rb 29 def expanded 30 tf = clone 31 tf.instance_variable_set(:@expanded, true) 32 tf 33 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 551 def format_type_alias_type(t, expand) 552 if @type_set.nil? 553 @bld << t.name 554 if expand && !Loader::StaticLoader::BUILTIN_ALIASES.include?(t.name) 555 @bld << ' = ' 556 append_string(t.resolved_type) 557 end 558 else 559 if expand && @type_set.defines_type?(t) 560 append_string(t.resolved_type) 561 else 562 @bld << @type_set.name_for(t, t.name) 563 end 564 end 565 end
# File lib/puppet/pops/types/type_formatter.rb 35 def indented(indent = 0, indent_width = 2) 36 tf = clone 37 tf.instance_variable_set(:@indent, indent) 38 tf.instance_variable_set(:@indent_width, indent_width) 39 tf 40 end
Produces an string containing newline characters and indentation that represents the given type or literal t.
@param t [Object] the type or literal to produce a string for @param indent [Integer] the current indentation level @param indent_width [Integer] the number of spaces to use for one indentation
@api public
# File lib/puppet/pops/types/type_formatter.rb 66 def indented_string(t, indent = 0, indent_width = 2) 67 @bld = String.new 68 append_indented_string(t, indent, indent_width) 69 @bld 70 end
# File lib/puppet/pops/types/type_formatter.rb 42 def ruby(ref_ctor) 43 tf = clone 44 tf.instance_variable_set(:@ruby, true) 45 tf.instance_variable_set(:@ref_ctor, ref_ctor) 46 tf 47 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 89 def ruby_string(ref_ctor, indent, t) 90 @ruby = true 91 @ref_ctor = ref_ctor 92 begin 93 indented_string(t, indent) 94 ensure 95 @ruby = nil 96 @ref_ctor = nil 97 end 98 end
Produces a string representing the type @api public
# File lib/puppet/pops/types/type_formatter.rb 52 def string(t) 53 @bld = String.new 54 append_string(t) 55 @bld 56 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 573 def string_Array(t) 574 append_array('') do 575 if @indent && !is_short_array?(t) 576 @indent += 1 577 t.each { |elem| newline; append_string(elem); @bld << COMMA_SEP } 578 chomp_list 579 @indent -= 1 580 newline 581 else 582 append_strings(t) 583 end 584 end 585 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 588 def string_FalseClass(t) ; @bld << 'false' ; end
@api private
# File lib/puppet/pops/types/type_formatter.rb 591 def string_Hash(t) 592 append_hash(t) 593 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 596 def string_Module(t) 597 append_string(TypeCalculator.singleton.type(t)) 598 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 601 def string_NilClass(t) ; @bld << (@ruby ? 'nil' : 'undef') ; end
@api private
# File lib/puppet/pops/types/type_formatter.rb 604 def string_Numeric(t) ; @bld << t.to_s ; end
# File lib/puppet/pops/types/type_formatter.rb 342 def string_Object(t) 343 type = TypeCalculator.infer(t) 344 if type.is_a?(PObjectTypeExtension) 345 type = type.base_type 346 end 347 if type.is_a?(PObjectType) 348 init_hash = type.extract_init_hash(t) 349 @bld << type.name << '(' 350 if @indent 351 append_indented_string(init_hash, @indent, @indent_width, true) 352 @bld.chomp! 353 else 354 append_string(init_hash) 355 end 356 @bld << ')' 357 else 358 @bld << 'Instance of ' 359 append_string(type) 360 end 361 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 458 def string_PAnnotatedMember(m) 459 hash = m._pcore_init_hash 460 if hash.size == 1 461 string(m.type) 462 else 463 string(hash) 464 end 465 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 145 def string_PAnyType(_) ; @bld << 'Any' ; end
@api private
# File lib/puppet/pops/types/type_formatter.rb 401 def string_PArrayType(t) 402 if t.has_empty_range? 403 append_array('Array') { append_strings([0, 0]) } 404 else 405 append_array('Array', t == PArrayType::DEFAULT) do 406 append_strings([t.element_type], true) 407 append_elements(range_array_part(t.size_type), true) 408 chomp_list 409 end 410 end 411 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 168 def string_PBinaryType(_) ; @bld << 'Binary' ; end
@api private
# File lib/puppet/pops/types/type_formatter.rb 154 def string_PBooleanType(t) 155 append_array('Boolean', t.value.nil?) { append_string(t.value) } 156 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 280 def string_PCallableType(t) 281 if t.return_type.nil? 282 append_array('Callable', t.param_types.nil?) { append_callable_params(t) } 283 else 284 if t.param_types.nil? 285 append_array('Callable', false) { append_strings([[], t.return_type], false) } 286 else 287 append_array('Callable', false) do 288 append_array('', false) { append_callable_params(t) } 289 @bld << COMMA_SEP 290 append_string(t.return_type) 291 end 292 end 293 end 294 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 427 def string_PCatalogEntryType(_) 428 @bld << 'CatalogEntry' 429 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 432 def string_PClassType(t) 433 append_array('Class', t.class_name.nil?) { append_elements([t.class_name]) } 434 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 337 def string_PCollectionType(t) 338 range = range_array_part(t.size_type) 339 append_array('Collection', range.empty? ) { append_elements(range) } 340 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 151 def string_PDefaultType(_) ; @bld << 'Default' ; end
@api private
# File lib/puppet/pops/types/type_formatter.rb 219 def string_PEnumType(t) 220 append_array('Enum', t.values.empty?) do 221 append_strings(t.values) 222 if t.case_insensitive? 223 @bld << COMMA_SEP 224 append_string(true) 225 end 226 end 227 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 196 def string_PFloatType(t) 197 append_array('Float', t.unbounded? ) { append_elements(range_array_part(t)) } 198 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 414 def string_PHashType(t) 415 if t.has_empty_range? 416 append_array('Hash') { append_strings([0, 0]) } 417 else 418 append_array('Hash', t == PHashType::DEFAULT) do 419 append_strings([t.key_type, t.value_type], true) 420 append_elements(range_array_part(t.size_type), true) 421 chomp_list 422 end 423 end 424 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 181 def string_PInitType(t) 182 append_array('Init', t.type.nil?) { append_strings([t.type, *t.init_args]) } 183 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 171 def string_PIntegerType(t) 172 append_array('Integer', t.unbounded?) { append_elements(range_array_part(t)) } 173 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 186 def string_PIterableType(t) 187 append_array('Iterable', t.element_type.nil?) { append_string(t.element_type) } 188 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 191 def string_PIteratorType(t) 192 append_array('Iterator', t.element_type.nil?) { append_string(t.element_type) } 193 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 446 def string_PNotUndefType(t) 447 contained_type = t.type 448 append_array('NotUndef', contained_type.nil? || contained_type.class == PAnyType) do 449 if contained_type.is_a?(PStringType) && !contained_type.value.nil? 450 append_string(contained_type.value) 451 else 452 append_string(contained_type) 453 end 454 end 455 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 165 def string_PNumericType(_) ; @bld << 'Numeric' ; end
@api private
# File lib/puppet/pops/types/type_formatter.rb 503 def string_PObjectType(t) 504 if @expanded 505 append_object_hash(t._pcore_init_hash(@type_set.nil? || !@type_set.defines_type?(t))) 506 else 507 @bld << (@type_set ? @type_set.name_for(t, t.label) : t.label) 508 end 509 end
# File lib/puppet/pops/types/type_formatter.rb 511 def string_PObjectTypeExtension(t) 512 append_array(@type_set ? @type_set.name_for(t, t.name) : t.name, false) do 513 ips = t.init_parameters 514 if ips.is_a?(Array) 515 append_strings(ips) 516 else 517 append_string(ips) 518 end 519 end 520 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 528 def string_POptionalType(t) 529 optional_type = t.optional_type 530 append_array('Optional', optional_type.nil?) do 531 if optional_type.is_a?(PStringType) && !optional_type.value.nil? 532 append_string(optional_type.value) 533 else 534 append_string(optional_type) 535 end 536 end 537 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 331 def string_PPatternType(t) 332 append_array('Pattern', t.patterns.empty?) { append_strings(t.patterns.map(&:regexp)) } 333 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 201 def string_PRegexpType(t) 202 append_array('Regexp', t.pattern.nil?) { append_string(t.regexp) } 203 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 437 def string_PResourceType(t) 438 if t.type_name 439 append_array(capitalize_segments(t.type_name), t.title.nil?) { append_string(t.title) } 440 else 441 @bld << 'Resource' 442 end 443 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 396 def string_PRuntimeType(t) 397 append_array('Runtime', t.runtime.nil? && t.name_or_pattern.nil?) { append_strings([t.runtime, t.name_or_pattern]) } 398 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 162 def string_PScalarDataType(_) ; @bld << 'ScalarData' ; end
@api private
# File lib/puppet/pops/types/type_formatter.rb 159 def string_PScalarType(_) ; @bld << 'Scalar' ; end
@api private
# File lib/puppet/pops/types/type_formatter.rb 240 def string_PSemVerRangeType(t) 241 @bld << 'SemVerRange' 242 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 235 def string_PSemVerType(t) 236 append_array('SemVer', t.ranges.empty?) { append_strings(t.ranges) } 237 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 523 def string_PSensitiveType(t) 524 append_array('Sensitive', PAnyType::DEFAULT == t.type) { append_string(t.type) } 525 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 206 def string_PStringType(t) 207 range = range_array_part(t.size_type) 208 append_array('String', range.empty? && !(@debug && !t.value.nil?)) do 209 if @debug 210 append_elements(range, !t.value.nil?) 211 append_string(t.value) unless t.value.nil? 212 else 213 append_elements(range) 214 end 215 end 216 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 313 def string_PStructType(t) 314 append_array('Struct', t.elements.empty?) { append_hash(Hash[t.elements.map {|e| struct_element_pair(e) }]) } 315 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 258 def string_PTimespanType(t) 259 min = t.from 260 max = t.to 261 append_array('Timespan', min.nil? && max.nil?) do 262 min.nil? ? append_default : append_string(min) 263 unless max.nil? || max == min 264 @bld << COMMA_SEP 265 append_string(max) 266 end 267 end 268 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 245 def string_PTimestampType(t) 246 min = t.from 247 max = t.to 248 append_array('Timestamp', min.nil? && max.nil?) do 249 min.nil? ? append_default : append_string(min) 250 unless max.nil? || max == min 251 @bld << COMMA_SEP 252 append_string(max) 253 end 254 end 255 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 271 def string_PTupleType(t) 272 append_array('Tuple', t.types.empty?) do 273 append_strings(t.types, true) 274 append_elements(range_array_part(t.size_type), true) 275 chomp_list 276 end 277 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 540 def string_PTypeAliasType(t) 541 expand = @expanded 542 if expand && t.self_recursion? 543 @guard ||= RecursionGuard.new 544 @guard.with_this(t) { |state| format_type_alias_type(t, (state & RecursionGuard::SELF_RECURSION_IN_THIS) == 0) } 545 else 546 format_type_alias_type(t, expand) 547 end 548 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 568 def string_PTypeReferenceType(t) 569 append_array('TypeReference') { append_string(t.type_string) } 570 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 475 def string_PTypeSetType(t) 476 append_array('TypeSet') do 477 append_hash(t._pcore_init_hash.each, proc { |k| @bld << symbolic_key(k) }) do |k,v| 478 case k 479 when KEY_TYPES 480 old_ts = @type_set 481 @type_set = t 482 begin 483 append_hash(v, proc { |tk| @bld << symbolic_key(tk) }) do |tk, tv| 484 if tv.is_a?(Hash) 485 append_object_hash(tv) 486 else 487 append_string(tv) 488 end 489 end 490 rescue 491 @type_set = old_ts 492 end 493 when KEY_REFERENCES 494 append_hash(v, proc { |tk| @bld << symbolic_key(tk) }) 495 else 496 append_string(v) 497 end 498 end 499 end 500 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 176 def string_PTypeType(t) 177 append_array('Type', t.type.nil?) { append_string(t.type) } 178 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 375 def string_PURIType(t) 376 append_array('URI', t.parameters.nil?) { append_string(t._pcore_init_hash['parameters']) } 377 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 148 def string_PUndefType(_) ; @bld << 'Undef' ; end
@api private
# File lib/puppet/pops/types/type_formatter.rb 391 def string_PUnitType(_) 392 @bld << 'Unit' 393 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 230 def string_PVariantType(t) 231 append_array('Variant', t.types.empty?) { append_strings(t.types) } 232 end
# File lib/puppet/pops/types/type_formatter.rb 363 def string_PuppetObject(t) 364 @bld << t._pcore_type.name << '(' 365 if @indent 366 append_indented_string(t._pcore_init_hash, @indent, @indent_width, true) 367 @bld.chomp! 368 else 369 append_string(t._pcore_init_hash) 370 end 371 @bld << ')' 372 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 607 def string_Regexp(t) ; @bld << PRegexpType.regexp_to_s_with_delimiters(t); end
@api private
# File lib/puppet/pops/types/type_formatter.rb 610 def string_String(t) 611 # Use single qoute on strings that does not contain single quotes, control characters, or backslashes. 612 @bld << StringConverter.singleton.puppet_quote(t) 613 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 616 def string_Symbol(t) ; @bld << t.to_s ; end
@api private
# File lib/puppet/pops/types/type_formatter.rb 628 def string_Timespan(t) ; @bld << "'#{t}'" ; end
@api private
# File lib/puppet/pops/types/type_formatter.rb 631 def string_Timestamp(t) ; @bld << "'#{t}'" ; end
@api private
# File lib/puppet/pops/types/type_formatter.rb 619 def string_TrueClass(t) ; @bld << 'true' ; end
# File lib/puppet/pops/types/type_formatter.rb 379 def string_URI(t) 380 @bld << 'URI(' 381 if @indent 382 append_indented_string(t.to_s, @indent, @indent_width, true) 383 @bld.chomp! 384 else 385 append_string(t.to_s) 386 end 387 @bld << ')' 388 end
@api private
# File lib/puppet/pops/types/type_formatter.rb 622 def string_Version(t) ; @bld << "'#{t}'" ; end
@api private
# File lib/puppet/pops/types/type_formatter.rb 625 def string_VersionRange(t) ; @bld << "'#{t}'" ; end
@api private
# File lib/puppet/pops/types/type_formatter.rb 318 def struct_element_pair(t) 319 k = t.key_type 320 value_optional = t.value_type.assignable?(PUndefType::DEFAULT) 321 if k.is_a?(POptionalType) 322 # Output as literal String 323 k = t.name if value_optional 324 else 325 k = value_optional ? PNotUndefType.new(k) : t.name 326 end 327 [k, t.value_type] 328 end
Used when printing names of well known keys in an Object type. Placed in a separate method to allow override. @api private
# File lib/puppet/pops/types/type_formatter.rb 470 def symbolic_key(key) 471 @ruby ? "'#{key}'" : key 472 end
Debugging to_s to reduce the amount of output
# File lib/puppet/pops/types/type_formatter.rb 634 def to_s 635 '[a TypeFormatter]' 636 end
Private Instance Methods
# File lib/puppet/pops/types/type_formatter.rb 755 def append_array(start, empty = false) 756 @bld << start 757 unless empty 758 @bld << '[' 759 yield 760 @bld << ']' 761 end 762 end
# File lib/puppet/pops/types/type_formatter.rb 728 def append_elements(array, to_be_continued = false) 729 case array.size 730 when 0 731 when 1 732 @bld << array[0] 733 @bld << COMMA_SEP if to_be_continued 734 else 735 array.each { |elem| @bld << elem << COMMA_SEP } 736 chomp_list unless to_be_continued 737 end 738 end
# File lib/puppet/pops/types/type_formatter.rb 764 def append_hash(hash, key_proc = nil) 765 @bld << '{' 766 @indent += 1 if @indent 767 hash.each do |k, v| 768 newline if @indent 769 if key_proc.nil? 770 append_string(k) 771 else 772 key_proc.call(k) 773 end 774 @bld << HASH_ENTRY_OP 775 if block_given? 776 yield(k, v) 777 else 778 append_string(v) 779 end 780 @bld << COMMA_SEP 781 end 782 chomp_list 783 if @indent 784 @indent -= 1 785 newline 786 end 787 @bld << '}' 788 end
# File lib/puppet/pops/types/type_formatter.rb 694 def append_object_hash(hash) 695 begin 696 @expanded = false 697 append_array('Object') do 698 append_hash(hash, proc { |k| @bld << symbolic_key(k) }) do |k,v| 699 case k 700 when KEY_ATTRIBUTES, KEY_FUNCTIONS 701 # Types might need to be output as type references 702 append_hash(v) do |_, fv| 703 if fv.is_a?(Hash) 704 append_hash(fv, proc { |fak| @bld << symbolic_key(fak) }) do |fak,fav| 705 case fak 706 when KEY_KIND 707 @bld << fav 708 else 709 append_string(fav) 710 end 711 end 712 else 713 append_string(fv) 714 end 715 end 716 when KEY_EQUALITY 717 append_array('') { append_strings(v) } if v.is_a?(Array) 718 else 719 append_string(v) 720 end 721 end 722 end 723 ensure 724 @expanded = true 725 end 726 end
# File lib/puppet/pops/types/type_formatter.rb 740 def append_strings(array, to_be_continued = false) 741 case array.size 742 when 0 743 when 1 744 append_string(array[0]) 745 @bld << COMMA_SEP if to_be_continued 746 else 747 array.each do |elem| 748 append_string(elem) 749 @bld << COMMA_SEP 750 end 751 chomp_list unless to_be_continued 752 end 753 end
# File lib/puppet/pops/types/type_formatter.rb 796 def chomp_list 797 @bld.chomp!(COMMA_SEP) 798 end
# File lib/puppet/pops/types/type_formatter.rb 669 def is_short_array?(t) 670 t.empty? || 100 - @indent * @indent_width > t.inject(0) do |sum, elem| 671 case elem 672 when true, false, nil, Numeric, Symbol 673 sum + elem.inspect.length() 674 when String 675 sum + 2 + elem.length 676 when Hash, Array 677 sum + (elem.empty? ? 2 : 1000) 678 else 679 sum + 1000 680 end 681 end 682 end
# File lib/puppet/pops/types/type_formatter.rb 790 def newline 791 @bld.rstrip! 792 @bld << "\n" 793 (@indent * @indent_width).times { @bld << ' ' } 794 end
# File lib/puppet/pops/types/type_formatter.rb 684 def range_array_part(t) 685 if t.nil? || t.unbounded? 686 EMPTY_ARRAY 687 else 688 result = [t.from.nil? ? 'default' : t.from.to_s] 689 result << t.to.to_s unless t.to.nil? 690 result 691 end 692 end