<commit_before>module Halibut

  # This is an abstract map with behaviour specific to HAL.
  #
  # spec spec spec
  class RelationMap
    extend Forwardable

    def_delegators :@relations, :[], :empty?, :==, :fetch

    def initialize
      @relations = {}
    end

    # Adds an object to a relation.
    #
    #     relations = RelationMap.new
    #     relations.add 'self', Link.new('/resource/1')
    #     relations['self']
    #     # => [#<Halibut::HAL::Link:0x007fa0ca5b92b8 @href=\"/resource/1\",
    #          @options=#<Halibut::HAL::Link::Options:0x007fa0ca5b9240
    #          @templated=nil, @type=nil, @name=nil, @profile=nil,
    #          @title=nil, @hreflang=nil>>]
    #
    # @param [String] relation relation that the object belongs to
    # @param [Object] item     the object to add to the relation
    def add(relation, item)
      @relations[relation] = @relations[relation].to_a << item
    end

    # Returns a hash corresponding to the object.
    #
    # RelationMap doens't just return @relations because it needs to convert
    # correctly when a relation only has a single item.
    #
    # @return [Hash] relation map in hash format
    def to_hash
      @relations.each_with_object({}) do |pair, obj|
        key, *value = pair.flatten

        key = key.to_s

        obj[key] = value.map &:to_hash
        obj[key].length == 1 and obj[key] = obj[key].first
      end
    end
  end
end<commit_msg>making use of destructuring syntax, and using #fetch as suggested on avdi's rubytapas<commit_after>module Halibut

  # This is an abstract map with behaviour specific to HAL.
  #
  # spec spec spec
  class RelationMap
    extend Forwardable

    def_delegators :@relations, :[], :empty?, :==, :fetch

    def initialize
      @relations = {}
    end

    # Adds an object to a relation.
    #
    #     relations = RelationMap.new
    #     relations.add 'self', Link.new('/resource/1')
    #     relations['self']
    #     # => [#<Halibut::HAL::Link:0x007fa0ca5b92b8 @href=\"/resource/1\",
    #          @options=#<Halibut::HAL::Link::Options:0x007fa0ca5b9240
    #          @templated=nil, @type=nil, @name=nil, @profile=nil,
    #          @title=nil, @hreflang=nil>>]
    #
    # @param [String] relation relation that the object belongs to
    # @param [Object] item     the object to add to the relation
    def add(relation, item)
      @relations[relation] = @relations.fetch(relation, []) << item
    end

    # Returns a hash corresponding to the object.
    #
    # RelationMap doens't just return @relations because it needs to convert
    # correctly when a relation only has a single item.
    #
    # @return [Hash] relation map in hash format
    def to_hash
      @relations.each_with_object({}) do |(rel,val), obj|
        rel = rel.to_s
        val = val.length == 1 ? val.first.to_hash : val.map(&:to_hash)

        obj[rel] = val
      end
    end
  end
end
{'fraction_non_alphanumeric': 0.1185743660041124, 'fraction_numerical': 0.015078821110349555, 'mean_word_length': 2.5684596577017116, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 9, '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': '1178560', 'n_tokens_mistral': 966, 'n_tokens_neox': 919, 'n_words': 267}