File: constants.rb

package info (click to toggle)
ruby-dry-core 0.7.1-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 396 kB
  • sloc: ruby: 2,126; sh: 4; makefile: 4
file content (117 lines) | stat: -rw-r--r-- 2,735 bytes parent folder | download
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