1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 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 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
# frozen_string_literal: true
require "set"
module Dry
module Core
# A list of constants you can use to avoid memory allocations or identity checks.
#
# @example Just include this module to your class or module
# class Foo
# include Dry::Core::Constants
# def call(value = EMPTY_ARRAY)
# value.map(&:to_s)
# end
# end
#
# @api public
module Constants
# An empty array
EMPTY_ARRAY = [].freeze
# An empty hash
EMPTY_HASH = {}.freeze
# An empty list of options
EMPTY_OPTS = {}.freeze
# An empty set
EMPTY_SET = ::Set.new.freeze
# An empty string
EMPTY_STRING = ""
# Identity function
IDENTITY = (-> x { x }).freeze
# A special value you can use as a default to know if no arguments
# were passed to the method
#
# @example
# def method(value = Undefined)
# if Undefined.equal?(value)
# puts 'no args'
# else
# puts value
# end
# end
Undefined = Object.new.tap do |undefined|
# @api private
Self = -> { Undefined } # rubocop:disable Lint/ConstantDefinitionInBlock
# @api public
def undefined.to_s
"Undefined"
end
# @api public
def undefined.inspect
"Undefined"
end
# Pick a value, if the first argument is not Undefined, return it back,
# otherwise return the second arg or yield the block.
#
# @example
# def method(val = Undefined)
# 1 + Undefined.default(val, 2)
# end
#
def undefined.default(x, y = self) # rubocop:disable Naming/MethodParameterName
if equal?(x)
if equal?(y)
yield
else
y
end
else
x
end
end
# Map a non-undefined value
#
# @example
# def add_five(val = Undefined)
# Undefined.map(val) { |x| x + 5 }
# end
#
def undefined.map(value)
if equal?(value)
self
else
yield(value)
end
end
# @api public
def undefined.dup
self
end
# @api public
def undefined.clone
self
end
# @api public
def undefined.coalesce(*args)
args.find(Self) { |x| !equal?(x) }
end
end.freeze
def self.included(base)
super
constants.each do |const_name|
base.const_set(const_name, const_get(const_name))
end
end
end
end
end
|