|
1 | 1 | # frozen_string_literal: true
|
2 | 2 |
|
3 |
| -module Enumerable |
4 |
| - INDEX_WITH_DEFAULT = Object.new |
5 |
| - private_constant :INDEX_WITH_DEFAULT |
| 3 | +module ActiveSupport |
| 4 | + module EnumerableCoreExt # :nodoc: |
| 5 | + module Constants |
| 6 | + private |
| 7 | + def const_missing(name) |
| 8 | + if name == :SoleItemExpectedError |
| 9 | + ::ActiveSupport::EnumerableCoreExt::SoleItemExpectedError |
| 10 | + else |
| 11 | + super |
| 12 | + end |
| 13 | + end |
| 14 | + end |
| 15 | + end |
| 16 | +end |
6 | 17 |
|
| 18 | +module Enumerable |
7 | 19 | # Error generated by +sole+ when called on an enumerable that doesn't have
|
8 | 20 | # exactly one item.
|
9 | 21 | class SoleItemExpectedError < StandardError; end
|
10 | 22 |
|
| 23 | + # HACK: For performance reasons, Enumerable shouldn't have any constants of its own. |
| 24 | + # So we move SoleItemExpectedError into ActiveSupport::EnumerableCoreExt. |
| 25 | + ActiveSupport::EnumerableCoreExt::SoleItemExpectedError = remove_const(:SoleItemExpectedError) |
| 26 | + singleton_class.prepend(ActiveSupport::EnumerableCoreExt::Constants) |
| 27 | + |
11 | 28 | # Enumerable#sum was added in Ruby 2.4, but it only works with Numeric elements
|
12 | 29 | # when we omit an identity.
|
13 | 30 |
|
@@ -106,17 +123,17 @@ def index_by
|
106 | 123 | #
|
107 | 124 | # %i( created_at updated_at ).index_with(Time.now)
|
108 | 125 | # # => { created_at: 2020-03-09 22:31:47, updated_at: 2020-03-09 22:31:47 }
|
109 |
| - def index_with(default = INDEX_WITH_DEFAULT) |
| 126 | + def index_with(default = (no_default = true)) |
110 | 127 | if block_given?
|
111 | 128 | result = {}
|
112 | 129 | each { |elem| result[elem] = yield(elem) }
|
113 | 130 | result
|
114 |
| - elsif default != INDEX_WITH_DEFAULT |
| 131 | + elsif no_default |
| 132 | + to_enum(:index_with) { size if respond_to?(:size) } |
| 133 | + else |
115 | 134 | result = {}
|
116 | 135 | each { |elem| result[elem] = default }
|
117 | 136 | result
|
118 |
| - else |
119 |
| - to_enum(:index_with) { size if respond_to?(:size) } |
120 | 137 | end
|
121 | 138 | end
|
122 | 139 |
|
@@ -240,8 +257,8 @@ def in_order_of(key, series)
|
240 | 257 | def sole
|
241 | 258 | case count
|
242 | 259 | when 1 then return first # rubocop:disable Style/RedundantReturn
|
243 |
| - when 0 then raise SoleItemExpectedError, "no item found" |
244 |
| - when 2.. then raise SoleItemExpectedError, "multiple items found" |
| 260 | + when 0 then raise ActiveSupport::EnumerableCoreExt::SoleItemExpectedError, "no item found" |
| 261 | + when 2.. then raise ActiveSupport::EnumerableCoreExt::SoleItemExpectedError, "multiple items found" |
245 | 262 | end
|
246 | 263 | end
|
247 | 264 | end
|
|
0 commit comments