class NameCollisionError < RuntimeError; end
class NameFormatError < RuntimeError; end

class Robot
  attr_accessor :name

  @@registry

  def initialize(args = {})
    @@registry ||= []
    @name_generator = args[:name_generator]
    @name = generate_name
    check_name_format
    check_name_collision
    @@registry << @name
  end

  def generate_name
    temp_name = ''

    if @name_generator
      temp_name = @name_generator.call
    else
      2.times { temp_name << ('A'..'Z').to_a.sample }
      3.times { temp_name << rand(10).to_s }
    end

    temp_name
  end

  def check_name_format
    unless name =~ /[[:alpha:]]{2}[[:digit:]]{3}/
      raise NameFormatError,
        'Robot name should be 2 letters and 3 numbers. Ex: AA111'
    end
  end

  def check_name_collision
    if @@registry.include?(name)
      raise NameCollisionError,
        'Robot name is already in the registry'
    end
  end
end

robot = Robot.new
puts "My pet robot's name is #{robot.name}, but we usually call him sparky."

# Errors!
# generator = -> { 'AA111' }
# Robot.new(name_generator: generator)
# Robot.new(name_generator: generator)

class NameCollisionError < RuntimeError; end
class NameFormatError < RuntimeError; end

class Robot
  attr_accessor :name

  @@registry

  def initialize(args = {})
    @@registry ||= []
    @name_generator = args[:name_generator]
    @name = generate_name
    check_name_format
    check_name_collision
    @@registry << @name
  end

  def generate_name
    temp_name = ''

    if @name_generator
      temp_name = @name_generator.call
    else
      2.times { temp_name << ('A'..'Z').to_a.sample }
      3.times { temp_name << rand(10).to_s }
    end

    temp_name
  end

  def check_name_format
    unless name =~ /[[:alpha:]]{2}[[:digit:]]{3}/
      raise NameFormatError,
        'Robot name should be 2 letters and 3 numbers. Ex: AA111'
    end
  end

  def check_name_collision
    if @@registry.include?(name)
      raise NameCollisionError,
        'Robot name is already in the registry'
    end
  end
end

robot = Robot.new
puts "My pet robot's name is #{robot.name}, but we usually call him sparky."

# Errors!
begin
generator = -> { 'AA111' }
Robot.new(name_generator: generator)
Robot.new(name_generator: generator)
rescue => e
  puts "Failed with: #{e.class}: #{e.message}"
end

begin
generator = -> { 'AA11' }
Robot.new(name_generator: generator)
rescue => e
  puts "Failed with: #{e.class}: #{e.message}"
end

Check both errors at once using begin/end
Check both errors at once using begin/end

This is a bit smelly because this code really belongs in a test
instead of at the bottom of the file. However, I want to focus
more on the main class itself right now and not so much creating
a test. How dare that be typed from my fingers!!!
