<commit_before>require 'forwardable'

class Robot
  class Direction
    Data = Struct.new(:prev_name, :next_name, :delta_x, :delta_y)

    extend Forwardable

    DATA = {
      'NORTH' => Data.new('WEST', 'EAST', 0, 1),
      'EAST' => Data.new('NORTH', 'SOUTH', 1, 0),
      'SOUTH' => Data.new('EAST', 'WEST', 0, -1),
      'WEST' => Data.new('SOUTH', 'NORTH', -1, 0)
    }.freeze

    def self.Direction direction
      return direction if direction.is_a? Direction

      Direction.new direction
    end

    attr_reader :name
    def_delegators :@data, :prev_name, :next_name, :delta_x, :delta_y

    def initialize name
      replace name
    end

    def == other
      @name == other.name
    end

    def next
      self.class.const_get next_name
    end

    def next!
      replace self.next
    end

    def prev
      self.class.const_get prev_name
    end

    def prev!
      replace prev
    end

    def to_s
      @name
    end

    private

    def replace other
      name = other.is_a?(String) ? other : other.name
      raise ArgumentError, "#{name}: unknown direction" \
	unless DATA.has_key? name

      @name, @data = name, DATA[name]
      self
    end

    public

    NORTH = Direction 'NORTH'
    EAST = Direction 'EAST'
    SOUTH = Direction 'SOUTH'
    WEST = Direction 'WEST'
    ALL = [NORTH, EAST, SOUTH, WEST].map! { |d| d.freeze }
  end
end

module Kernel
  def Direction direction
    Robot::Direction::Direction direction
  end
end
<commit_msg>* Refactor. Better naming.<commit_after>require 'forwardable'

class Robot
  class Direction
    Definition = Struct.new(:prev_name, :next_name, :delta_x, :delta_y)

    extend Forwardable

    DEFINITIONS = {
      'NORTH' => Definition.new('WEST', 'EAST', 0, 1),
      'EAST' => Definition.new('NORTH', 'SOUTH', 1, 0),
      'SOUTH' => Definition.new('EAST', 'WEST', 0, -1),
      'WEST' => Definition.new('SOUTH', 'NORTH', -1, 0)
    }.freeze

    def self.Direction direction
      return direction if direction.is_a? Direction

      Direction.new direction
    end

    attr_reader :name
    def_delegators :@data, :prev_name, :next_name, :delta_x, :delta_y

    def initialize name
      replace name
    end

    def == other
      @name == other.name
    end

    def next
      self.class.const_get next_name
    end

    def next!
      replace self.next
    end

    def prev
      self.class.const_get prev_name
    end

    def prev!
      replace prev
    end

    def to_s
      @name
    end

    private

    def replace other
      name = other.is_a?(String) ? other : other.name
      raise ArgumentError, "#{name}: unknown direction" \
	unless DEFINITIONS.has_key? name

      @name, @data = name, DEFINITIONS[name]
      self
    end

    public

    NORTH = Direction 'NORTH'
    EAST = Direction 'EAST'
    SOUTH = Direction 'SOUTH'
    WEST = Direction 'WEST'
    ALL = [NORTH, EAST, SOUTH, WEST].map! { |d| d.freeze }
  end
end

module Kernel
  def Direction direction
    Robot::Direction::Direction direction
  end
end

{'fraction_non_alphanumeric': 0.10924092409240924, 'fraction_numerical': 0.005280528052805281, 'mean_word_length': 2.3903803131991053, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1019002', 'n_tokens_mistral': 1096, 'n_tokens_neox': 1031, 'n_words': 287}