Class: Ryac::NameGenerator

Inherits:
Object
  • Object
show all
Defined in:
lib/ryac/name_generator.rb,
sig/ryac/name_generator.rbs

Overview

Generates sequential short names for variable mangling a, b, ..., z, a0, a1, ..., z9, a0a, a0b, ..., z9z, ...

Constant Summary collapse

LETTERS =

Returns:

  • (Array[String])
('a'..'z').to_a.freeze
DIGITS =

Returns:

  • (Array[String])
('0'..'9').to_a.freeze
KEPT_NAME_MAX =

A one- or two-character name is as short as this generator's own output; the rename families keep such names untouched, so a second minification pass reassigns nothing and the output is a fixed point.

Returns:

  • (Integer)
2

Instance Method Summary collapse

Constructor Details

#initialize(additional_excluded = [], prefix: "", upcase: false) ⇒ NameGenerator

additional_excluded holds FINAL names — prefix and case included — which is what every caller has in hand (kept originals, reserved names). Comparing before prefixing would make seeding useless to the prefixed families and force each to re-check by hand.

Parameters:

  • additional_excluded (?(Array[String] | Set[String])) (defaults to: [])
  • prefix: (String) (defaults to: "")
  • upcase: (Boolean) (defaults to: false)


19
20
21
22
23
24
# File 'lib/ryac/name_generator.rb', line 19

def initialize(additional_excluded = [], prefix: "", upcase: false)
  @index = 0
  @prefix = prefix
  @upcase = upcase
  @excluded = Set.new(additional_excluded)
end

Instance Method Details

#index_to_name(index) ⇒ String

Convert index to name using letter-digit alternating scheme: a-z, a0-z9, a0a-z9z, a0a0-z9z9, ...

Parameters:

  • index (Integer)

Returns:

  • (String)


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
# File 'lib/ryac/name_generator.rb', line 41

def index_to_name(index)
  return LETTERS[index] if index < 26

  index -= 26
  length = 2
  capacity = 26 * 10

  while index >= capacity
    index -= capacity
    length += 1
    capacity *= (length.odd? ? 26 : 10)
  end

  result = ""
  (length - 1).downto(0) do |pos|
    if pos.even?
      result = LETTERS[index % 26] + result
      index /= 26
    else
      result = DIGITS[index % 10] + result
      index /= 10
    end
  end
  result
end

#next_name ⇒ String

Returns:

  • (String)


26
27
28
29
30
31
32
33
34
35
# File 'lib/ryac/name_generator.rb', line 26

def next_name
  loop do
    name = index_to_name(@index)
    @index += 1
    name = name.upcase if @upcase
    final = "#{@prefix}#{name}"
    next if @excluded.include?(final)
    return final
  end
end