Sha256: b4e24410d29035ee28c70ef7ff56688aaa849f37bdcccb8431a405184850bd9b

Contents?: true

Size: 1.96 KB

Versions: 1

Compression:

Stored size: 1.96 KB

Contents

# frozen_string_literal: true

# Mixin for combining variations
#
#   { a: :b }.expand       #=> [{ a: :b }]
#   { a: [:b, :c] }.expand #=> [{ a: :b }, { a: :c }]
#   {
#     a: [:b, :c],
#     d: [:e, :f],
#   }.expand
#   #=> [{ a: :b, d: :e }, {a: :b, d: :f}, { a: :c, d: :e }, { a: :c, d: :f }]
module Expandable
  # Returns an array composed of all possible variation of the object by
  # combining all the items of it's array values.
  #
  # @return [Array]
  def expand
    @expand_res = [{}]
    each do |key, value|
      case value
      when Array then expand_array(key)
      when Hash then expand_hash(key)
      else @expand_res.map! { |hash| hash.merge(key => value) }
      end
    end
    @expand_res
  end

  private

  def expand_array(key) # rubocop:disable Metrics/MethodLength
    orig = @expand_res
    @expand_res = []
    fetch(key).each do |value|
      if value.respond_to?(:expand)
        value.expand.each do |v|
          @expand_res += orig.map { |hash| hash.merge(key => v) }
        end
      else
        @expand_res += orig.map { |hash| hash.merge(key => value) }
      end
    end
  end

  def expand_hash(key) # rubocop:disable Metrics/MethodLength
    orig = @expand_res
    @expand_res = []
    fetch(key).expand.each do |value|
      if value.respond_to?(:expand)
        value.expand.each do |v|
          @expand_res += orig.map { |hash| hash.merge(key => v) }
        end
      else
        @expand_res += orig.map { |hash| hash.merge(key => value) }
      end
    end
  end
end

class Array # :nodoc:
  def deep_dup
    map do |value|
      if value.respond_to?(:deep_dup)
        value.deep_dup
      else
        value.dup
      end
    end
  end
end

class Hash # :nodoc:
  include Expandable

  def deep_dup
    hash = dup
    each_pair do |key, value|
      hash[key.dup] = if value.respond_to?(:deep_dup)
                        value.deep_dup
                      else
                        value.dup
                      end
    end
    hash
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
puffy-1.0.0 lib/core_ext.rb