activesupport 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +572 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +40 -0
- data/lib/active_support.rb +96 -0
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +5 -0
- data/lib/active_support/array_inquirer.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +132 -0
- data/lib/active_support/benchmarkable.rb +51 -0
- data/lib/active_support/builder.rb +8 -0
- data/lib/active_support/cache.rb +830 -0
- data/lib/active_support/cache/file_store.rb +196 -0
- data/lib/active_support/cache/mem_cache_store.rb +212 -0
- data/lib/active_support/cache/memory_store.rb +174 -0
- data/lib/active_support/cache/null_store.rb +48 -0
- data/lib/active_support/cache/redis_cache_store.rb +488 -0
- data/lib/active_support/cache/strategy/local_cache.rb +194 -0
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
- data/lib/active_support/callbacks.rb +856 -0
- data/lib/active_support/concern.rb +171 -0
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +17 -0
- data/lib/active_support/concurrency/share_lock.rb +227 -0
- data/lib/active_support/configurable.rb +146 -0
- data/lib/active_support/core_ext.rb +5 -0
- data/lib/active_support/core_ext/array.rb +9 -0
- data/lib/active_support/core_ext/array/access.rb +104 -0
- data/lib/active_support/core_ext/array/conversions.rb +213 -0
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/extract_options.rb +31 -0
- data/lib/active_support/core_ext/array/grouping.rb +109 -0
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +5 -0
- data/lib/active_support/core_ext/array/wrap.rb +48 -0
- data/lib/active_support/core_ext/benchmark.rb +16 -0
- data/lib/active_support/core_ext/big_decimal.rb +3 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
- data/lib/active_support/core_ext/class.rb +4 -0
- data/lib/active_support/core_ext/class/attribute.rb +141 -0
- data/lib/active_support/core_ext/class/attribute_accessors.rb +6 -0
- data/lib/active_support/core_ext/class/subclasses.rb +54 -0
- data/lib/active_support/core_ext/date.rb +7 -0
- data/lib/active_support/core_ext/date/acts_like.rb +10 -0
- data/lib/active_support/core_ext/date/blank.rb +14 -0
- data/lib/active_support/core_ext/date/calculations.rb +146 -0
- data/lib/active_support/core_ext/date/conversions.rb +96 -0
- data/lib/active_support/core_ext/date/zones.rb +8 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +351 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +41 -0
- data/lib/active_support/core_ext/date_time.rb +7 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +16 -0
- data/lib/active_support/core_ext/date_time/blank.rb +14 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +211 -0
- data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +107 -0
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/digest/uuid.rb +53 -0
- data/lib/active_support/core_ext/enumerable.rb +188 -0
- data/lib/active_support/core_ext/file.rb +3 -0
- data/lib/active_support/core_ext/file/atomic.rb +70 -0
- data/lib/active_support/core_ext/hash.rb +10 -0
- data/lib/active_support/core_ext/hash/compact.rb +5 -0
- data/lib/active_support/core_ext/hash/conversions.rb +263 -0
- data/lib/active_support/core_ext/hash/deep_merge.rb +34 -0
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +24 -0
- data/lib/active_support/core_ext/hash/indifferent_access.rb +24 -0
- data/lib/active_support/core_ext/hash/keys.rb +143 -0
- data/lib/active_support/core_ext/hash/reverse_merge.rb +25 -0
- data/lib/active_support/core_ext/hash/slice.rb +26 -0
- data/lib/active_support/core_ext/hash/transform_values.rb +5 -0
- data/lib/active_support/core_ext/integer.rb +5 -0
- data/lib/active_support/core_ext/integer/inflections.rb +31 -0
- data/lib/active_support/core_ext/integer/multiple.rb +12 -0
- data/lib/active_support/core_ext/integer/time.rb +22 -0
- data/lib/active_support/core_ext/kernel.rb +5 -0
- data/lib/active_support/core_ext/kernel/concern.rb +14 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +45 -0
- data/lib/active_support/core_ext/kernel/singleton_class.rb +8 -0
- data/lib/active_support/core_ext/load_error.rb +9 -0
- data/lib/active_support/core_ext/marshal.rb +24 -0
- data/lib/active_support/core_ext/module.rb +13 -0
- data/lib/active_support/core_ext/module/aliasing.rb +31 -0
- data/lib/active_support/core_ext/module/anonymous.rb +30 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +38 -0
- data/lib/active_support/core_ext/module/attribute_accessors.rb +212 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +144 -0
- data/lib/active_support/core_ext/module/concerning.rb +134 -0
- data/lib/active_support/core_ext/module/delegation.rb +313 -0
- data/lib/active_support/core_ext/module/deprecation.rb +25 -0
- data/lib/active_support/core_ext/module/introspection.rb +86 -0
- data/lib/active_support/core_ext/module/reachable.rb +6 -0
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +17 -0
- data/lib/active_support/core_ext/name_error.rb +38 -0
- data/lib/active_support/core_ext/numeric.rb +5 -0
- data/lib/active_support/core_ext/numeric/bytes.rb +66 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +136 -0
- data/lib/active_support/core_ext/numeric/inquiry.rb +5 -0
- data/lib/active_support/core_ext/numeric/time.rb +66 -0
- data/lib/active_support/core_ext/object.rb +16 -0
- data/lib/active_support/core_ext/object/acts_like.rb +21 -0
- data/lib/active_support/core_ext/object/blank.rb +155 -0
- data/lib/active_support/core_ext/object/conversions.rb +6 -0
- data/lib/active_support/core_ext/object/deep_dup.rb +55 -0
- data/lib/active_support/core_ext/object/duplicable.rb +49 -0
- data/lib/active_support/core_ext/object/inclusion.rb +29 -0
- data/lib/active_support/core_ext/object/instance_variables.rb +30 -0
- data/lib/active_support/core_ext/object/json.rb +228 -0
- data/lib/active_support/core_ext/object/to_param.rb +3 -0
- data/lib/active_support/core_ext/object/to_query.rb +89 -0
- data/lib/active_support/core_ext/object/try.rb +156 -0
- data/lib/active_support/core_ext/object/with_options.rb +82 -0
- data/lib/active_support/core_ext/range.rb +7 -0
- data/lib/active_support/core_ext/range/compare_range.rb +70 -0
- data/lib/active_support/core_ext/range/conversions.rb +41 -0
- data/lib/active_support/core_ext/range/each.rb +25 -0
- data/lib/active_support/core_ext/range/include_range.rb +9 -0
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
- data/lib/active_support/core_ext/range/overlaps.rb +10 -0
- data/lib/active_support/core_ext/regexp.rb +7 -0
- data/lib/active_support/core_ext/securerandom.rb +45 -0
- data/lib/active_support/core_ext/string.rb +15 -0
- data/lib/active_support/core_ext/string/access.rb +114 -0
- data/lib/active_support/core_ext/string/behavior.rb +8 -0
- data/lib/active_support/core_ext/string/conversions.rb +59 -0
- data/lib/active_support/core_ext/string/exclude.rb +13 -0
- data/lib/active_support/core_ext/string/filters.rb +145 -0
- data/lib/active_support/core_ext/string/indent.rb +45 -0
- data/lib/active_support/core_ext/string/inflections.rb +259 -0
- data/lib/active_support/core_ext/string/inquiry.rb +15 -0
- data/lib/active_support/core_ext/string/multibyte.rb +58 -0
- data/lib/active_support/core_ext/string/output_safety.rb +314 -0
- data/lib/active_support/core_ext/string/starts_ends_with.rb +6 -0
- data/lib/active_support/core_ext/string/strip.rb +27 -0
- data/lib/active_support/core_ext/string/zones.rb +16 -0
- data/lib/active_support/core_ext/time.rb +7 -0
- data/lib/active_support/core_ext/time/acts_like.rb +10 -0
- data/lib/active_support/core_ext/time/calculations.rb +344 -0
- data/lib/active_support/core_ext/time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/time/conversions.rb +72 -0
- data/lib/active_support/core_ext/time/zones.rb +113 -0
- data/lib/active_support/core_ext/uri.rb +25 -0
- data/lib/active_support/current_attributes.rb +203 -0
- data/lib/active_support/dependencies.rb +806 -0
- data/lib/active_support/dependencies/autoload.rb +79 -0
- data/lib/active_support/dependencies/interlock.rb +57 -0
- data/lib/active_support/dependencies/zeitwerk_integration.rb +110 -0
- data/lib/active_support/deprecation.rb +46 -0
- data/lib/active_support/deprecation/behaviors.rb +109 -0
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/instance_delegator.rb +39 -0
- data/lib/active_support/deprecation/method_wrappers.rb +78 -0
- data/lib/active_support/deprecation/proxy_wrappers.rb +173 -0
- data/lib/active_support/deprecation/reporting.rb +114 -0
- data/lib/active_support/descendants_tracker.rb +109 -0
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration.rb +433 -0
- data/lib/active_support/duration/iso8601_parser.rb +124 -0
- data/lib/active_support/duration/iso8601_serializer.rb +54 -0
- data/lib/active_support/encrypted_configuration.rb +45 -0
- data/lib/active_support/encrypted_file.rb +100 -0
- data/lib/active_support/evented_file_update_checker.rb +235 -0
- data/lib/active_support/execution_wrapper.rb +129 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +163 -0
- data/lib/active_support/gem_version.rb +17 -0
- data/lib/active_support/gzip.rb +38 -0
- data/lib/active_support/hash_with_indifferent_access.rb +399 -0
- data/lib/active_support/i18n.rb +16 -0
- data/lib/active_support/i18n_railtie.rb +126 -0
- data/lib/active_support/inflections.rb +72 -0
- data/lib/active_support/inflector.rb +9 -0
- data/lib/active_support/inflector/inflections.rb +257 -0
- data/lib/active_support/inflector/methods.rb +398 -0
- data/lib/active_support/inflector/transliterate.rb +147 -0
- data/lib/active_support/json.rb +4 -0
- data/lib/active_support/json/decoding.rb +76 -0
- data/lib/active_support/json/encoding.rb +134 -0
- data/lib/active_support/key_generator.rb +41 -0
- data/lib/active_support/lazy_load_hooks.rb +82 -0
- data/lib/active_support/locale/en.rb +31 -0
- data/lib/active_support/locale/en.yml +135 -0
- data/lib/active_support/log_subscriber.rb +135 -0
- data/lib/active_support/log_subscriber/test_helper.rb +106 -0
- data/lib/active_support/logger.rb +93 -0
- data/lib/active_support/logger_silence.rb +45 -0
- data/lib/active_support/logger_thread_safe_level.rb +56 -0
- data/lib/active_support/message_encryptor.rb +227 -0
- data/lib/active_support/message_verifier.rb +205 -0
- data/lib/active_support/messages/metadata.rb +71 -0
- data/lib/active_support/messages/rotation_configuration.rb +22 -0
- data/lib/active_support/messages/rotator.rb +56 -0
- data/lib/active_support/multibyte.rb +23 -0
- data/lib/active_support/multibyte/chars.rb +216 -0
- data/lib/active_support/multibyte/unicode.rb +157 -0
- data/lib/active_support/notifications.rb +253 -0
- data/lib/active_support/notifications/fanout.rb +244 -0
- data/lib/active_support/notifications/instrumenter.rb +164 -0
- data/lib/active_support/number_helper.rb +378 -0
- data/lib/active_support/number_helper/number_converter.rb +184 -0
- data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +31 -0
- data/lib/active_support/number_helper/number_to_human_converter.rb +70 -0
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +61 -0
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
- data/lib/active_support/number_helper/number_to_phone_converter.rb +60 -0
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +56 -0
- data/lib/active_support/number_helper/rounding_helper.rb +66 -0
- data/lib/active_support/option_merger.rb +27 -0
- data/lib/active_support/ordered_hash.rb +50 -0
- data/lib/active_support/ordered_options.rb +85 -0
- data/lib/active_support/parameter_filter.rb +129 -0
- data/lib/active_support/per_thread_registry.rb +60 -0
- data/lib/active_support/proxy_object.rb +15 -0
- data/lib/active_support/rails.rb +29 -0
- data/lib/active_support/railtie.rb +80 -0
- data/lib/active_support/reloader.rb +130 -0
- data/lib/active_support/rescuable.rb +174 -0
- data/lib/active_support/security_utils.rb +31 -0
- data/lib/active_support/string_inquirer.rb +34 -0
- data/lib/active_support/subscriber.rb +169 -0
- data/lib/active_support/tagged_logging.rb +88 -0
- data/lib/active_support/test_case.rb +163 -0
- data/lib/active_support/testing/assertions.rb +228 -0
- data/lib/active_support/testing/autorun.rb +7 -0
- data/lib/active_support/testing/constant_lookup.rb +51 -0
- data/lib/active_support/testing/declarative.rb +28 -0
- data/lib/active_support/testing/deprecation.rb +38 -0
- data/lib/active_support/testing/file_fixtures.rb +38 -0
- data/lib/active_support/testing/isolation.rb +110 -0
- data/lib/active_support/testing/method_call_assertions.rb +70 -0
- data/lib/active_support/testing/parallelization.rb +128 -0
- data/lib/active_support/testing/setup_and_teardown.rb +55 -0
- data/lib/active_support/testing/stream.rb +44 -0
- data/lib/active_support/testing/tagged_logging.rb +27 -0
- data/lib/active_support/testing/time_helpers.rb +200 -0
- data/lib/active_support/time.rb +20 -0
- data/lib/active_support/time_with_zone.rb +561 -0
- data/lib/active_support/values/time_zone.rb +570 -0
- data/lib/active_support/version.rb +10 -0
- data/lib/active_support/xml_mini.rb +202 -0
- data/lib/active_support/xml_mini/jdom.rb +183 -0
- data/lib/active_support/xml_mini/libxml.rb +80 -0
- data/lib/active_support/xml_mini/libxmlsax.rb +83 -0
- data/lib/active_support/xml_mini/nokogiri.rb +83 -0
- data/lib/active_support/xml_mini/nokogirisax.rb +86 -0
- data/lib/active_support/xml_mini/rexml.rb +130 -0
- metadata +385 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_support/array_inquirer"
|
|
4
|
+
|
|
5
|
+
class Array
|
|
6
|
+
# Wraps the array in an +ArrayInquirer+ object, which gives a friendlier way
|
|
7
|
+
# to check its string-like contents.
|
|
8
|
+
#
|
|
9
|
+
# pets = [:cat, :dog].inquiry
|
|
10
|
+
#
|
|
11
|
+
# pets.cat? # => true
|
|
12
|
+
# pets.ferret? # => false
|
|
13
|
+
#
|
|
14
|
+
# pets.any?(:cat, :ferret) # => true
|
|
15
|
+
# pets.any?(:ferret, :alligator) # => false
|
|
16
|
+
def inquiry
|
|
17
|
+
ActiveSupport::ArrayInquirer.new(self)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_support/deprecation"
|
|
4
|
+
|
|
5
|
+
ActiveSupport::Deprecation.warn "Ruby 2.5+ (required by Rails 6) provides Array#append and Array#prepend natively, so requiring active_support/core_ext/array/prepend_and_append is no longer necessary. Requiring it will raise LoadError in Rails 6.1."
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Array
|
|
4
|
+
# Wraps its argument in an array unless it is already an array (or array-like).
|
|
5
|
+
#
|
|
6
|
+
# Specifically:
|
|
7
|
+
#
|
|
8
|
+
# * If the argument is +nil+ an empty array is returned.
|
|
9
|
+
# * Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned.
|
|
10
|
+
# * Otherwise, returns an array with the argument as its single element.
|
|
11
|
+
#
|
|
12
|
+
# Array.wrap(nil) # => []
|
|
13
|
+
# Array.wrap([1, 2, 3]) # => [1, 2, 3]
|
|
14
|
+
# Array.wrap(0) # => [0]
|
|
15
|
+
#
|
|
16
|
+
# This method is similar in purpose to <tt>Kernel#Array</tt>, but there are some differences:
|
|
17
|
+
#
|
|
18
|
+
# * If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt>
|
|
19
|
+
# moves on to try +to_a+ if the returned value is +nil+, but <tt>Array.wrap</tt> returns
|
|
20
|
+
# an array with the argument as its single element right away.
|
|
21
|
+
# * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt>
|
|
22
|
+
# raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value.
|
|
23
|
+
# * It does not call +to_a+ on the argument, if the argument does not respond to +to_ary+
|
|
24
|
+
# it returns an array with the argument as its single element.
|
|
25
|
+
#
|
|
26
|
+
# The last point is easily explained with some enumerables:
|
|
27
|
+
#
|
|
28
|
+
# Array(foo: :bar) # => [[:foo, :bar]]
|
|
29
|
+
# Array.wrap(foo: :bar) # => [{:foo=>:bar}]
|
|
30
|
+
#
|
|
31
|
+
# There's also a related idiom that uses the splat operator:
|
|
32
|
+
#
|
|
33
|
+
# [*object]
|
|
34
|
+
#
|
|
35
|
+
# which returns <tt>[]</tt> for +nil+, but calls to <tt>Array(object)</tt> otherwise.
|
|
36
|
+
#
|
|
37
|
+
# The differences with <tt>Kernel#Array</tt> explained above
|
|
38
|
+
# apply to the rest of <tt>object</tt>s.
|
|
39
|
+
def self.wrap(object)
|
|
40
|
+
if object.nil?
|
|
41
|
+
[]
|
|
42
|
+
elsif object.respond_to?(:to_ary)
|
|
43
|
+
object.to_ary || [object]
|
|
44
|
+
else
|
|
45
|
+
[object]
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "benchmark"
|
|
4
|
+
|
|
5
|
+
class << Benchmark
|
|
6
|
+
# Benchmark realtime in milliseconds.
|
|
7
|
+
#
|
|
8
|
+
# Benchmark.realtime { User.all }
|
|
9
|
+
# # => 8.0e-05
|
|
10
|
+
#
|
|
11
|
+
# Benchmark.ms { User.all }
|
|
12
|
+
# # => 0.074
|
|
13
|
+
def ms
|
|
14
|
+
1000 * realtime { yield }
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bigdecimal"
|
|
4
|
+
require "bigdecimal/util"
|
|
5
|
+
|
|
6
|
+
module ActiveSupport
|
|
7
|
+
module BigDecimalWithDefaultFormat #:nodoc:
|
|
8
|
+
def to_s(format = "F")
|
|
9
|
+
super(format)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
BigDecimal.prepend(ActiveSupport::BigDecimalWithDefaultFormat)
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_support/core_ext/kernel/singleton_class"
|
|
4
|
+
require "active_support/core_ext/module/redefine_method"
|
|
5
|
+
require "active_support/core_ext/array/extract_options"
|
|
6
|
+
|
|
7
|
+
class Class
|
|
8
|
+
# Declare a class-level attribute whose value is inheritable by subclasses.
|
|
9
|
+
# Subclasses can change their own value and it will not impact parent class.
|
|
10
|
+
#
|
|
11
|
+
# ==== Options
|
|
12
|
+
#
|
|
13
|
+
# * <tt>:instance_reader</tt> - Sets the instance reader method (defaults to true).
|
|
14
|
+
# * <tt>:instance_writer</tt> - Sets the instance writer method (defaults to true).
|
|
15
|
+
# * <tt>:instance_accessor</tt> - Sets both instance methods (defaults to true).
|
|
16
|
+
# * <tt>:instance_predicate</tt> - Sets a predicate method (defaults to true).
|
|
17
|
+
# * <tt>:default</tt> - Sets a default value for the attribute (defaults to nil).
|
|
18
|
+
#
|
|
19
|
+
# ==== Examples
|
|
20
|
+
#
|
|
21
|
+
# class Base
|
|
22
|
+
# class_attribute :setting
|
|
23
|
+
# end
|
|
24
|
+
#
|
|
25
|
+
# class Subclass < Base
|
|
26
|
+
# end
|
|
27
|
+
#
|
|
28
|
+
# Base.setting = true
|
|
29
|
+
# Subclass.setting # => true
|
|
30
|
+
# Subclass.setting = false
|
|
31
|
+
# Subclass.setting # => false
|
|
32
|
+
# Base.setting # => true
|
|
33
|
+
#
|
|
34
|
+
# In the above case as long as Subclass does not assign a value to setting
|
|
35
|
+
# by performing <tt>Subclass.setting = _something_</tt>, <tt>Subclass.setting</tt>
|
|
36
|
+
# would read value assigned to parent class. Once Subclass assigns a value then
|
|
37
|
+
# the value assigned by Subclass would be returned.
|
|
38
|
+
#
|
|
39
|
+
# This matches normal Ruby method inheritance: think of writing an attribute
|
|
40
|
+
# on a subclass as overriding the reader method. However, you need to be aware
|
|
41
|
+
# when using +class_attribute+ with mutable structures as +Array+ or +Hash+.
|
|
42
|
+
# In such cases, you don't want to do changes in place. Instead use setters:
|
|
43
|
+
#
|
|
44
|
+
# Base.setting = []
|
|
45
|
+
# Base.setting # => []
|
|
46
|
+
# Subclass.setting # => []
|
|
47
|
+
#
|
|
48
|
+
# # Appending in child changes both parent and child because it is the same object:
|
|
49
|
+
# Subclass.setting << :foo
|
|
50
|
+
# Base.setting # => [:foo]
|
|
51
|
+
# Subclass.setting # => [:foo]
|
|
52
|
+
#
|
|
53
|
+
# # Use setters to not propagate changes:
|
|
54
|
+
# Base.setting = []
|
|
55
|
+
# Subclass.setting += [:foo]
|
|
56
|
+
# Base.setting # => []
|
|
57
|
+
# Subclass.setting # => [:foo]
|
|
58
|
+
#
|
|
59
|
+
# For convenience, an instance predicate method is defined as well.
|
|
60
|
+
# To skip it, pass <tt>instance_predicate: false</tt>.
|
|
61
|
+
#
|
|
62
|
+
# Subclass.setting? # => false
|
|
63
|
+
#
|
|
64
|
+
# Instances may overwrite the class value in the same way:
|
|
65
|
+
#
|
|
66
|
+
# Base.setting = true
|
|
67
|
+
# object = Base.new
|
|
68
|
+
# object.setting # => true
|
|
69
|
+
# object.setting = false
|
|
70
|
+
# object.setting # => false
|
|
71
|
+
# Base.setting # => true
|
|
72
|
+
#
|
|
73
|
+
# To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
|
|
74
|
+
#
|
|
75
|
+
# object.setting # => NoMethodError
|
|
76
|
+
# object.setting? # => NoMethodError
|
|
77
|
+
#
|
|
78
|
+
# To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
|
|
79
|
+
#
|
|
80
|
+
# object.setting = false # => NoMethodError
|
|
81
|
+
#
|
|
82
|
+
# To opt out of both instance methods, pass <tt>instance_accessor: false</tt>.
|
|
83
|
+
#
|
|
84
|
+
# To set a default value for the attribute, pass <tt>default:</tt>, like so:
|
|
85
|
+
#
|
|
86
|
+
# class_attribute :settings, default: {}
|
|
87
|
+
def class_attribute(
|
|
88
|
+
*attrs,
|
|
89
|
+
instance_accessor: true,
|
|
90
|
+
instance_reader: instance_accessor,
|
|
91
|
+
instance_writer: instance_accessor,
|
|
92
|
+
instance_predicate: true,
|
|
93
|
+
default: nil
|
|
94
|
+
)
|
|
95
|
+
attrs.each do |name|
|
|
96
|
+
singleton_class.silence_redefinition_of_method(name)
|
|
97
|
+
define_singleton_method(name) { default }
|
|
98
|
+
|
|
99
|
+
singleton_class.silence_redefinition_of_method("#{name}?")
|
|
100
|
+
define_singleton_method("#{name}?") { !!public_send(name) } if instance_predicate
|
|
101
|
+
|
|
102
|
+
ivar = "@#{name}".to_sym
|
|
103
|
+
|
|
104
|
+
singleton_class.silence_redefinition_of_method("#{name}=")
|
|
105
|
+
define_singleton_method("#{name}=") do |val|
|
|
106
|
+
redefine_singleton_method(name) { val }
|
|
107
|
+
|
|
108
|
+
if singleton_class?
|
|
109
|
+
class_eval do
|
|
110
|
+
redefine_method(name) do
|
|
111
|
+
if instance_variable_defined? ivar
|
|
112
|
+
instance_variable_get ivar
|
|
113
|
+
else
|
|
114
|
+
singleton_class.send name
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
val
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
if instance_reader
|
|
123
|
+
redefine_method(name) do
|
|
124
|
+
if instance_variable_defined?(ivar)
|
|
125
|
+
instance_variable_get ivar
|
|
126
|
+
else
|
|
127
|
+
self.class.public_send name
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
redefine_method("#{name}?") { !!public_send(name) } if instance_predicate
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
if instance_writer
|
|
135
|
+
redefine_method("#{name}=") do |val|
|
|
136
|
+
instance_variable_set ivar, val
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# cattr_* became mattr_* aliases in 7dfbd91b0780fbd6a1dd9bfbc176e10894871d2d,
|
|
4
|
+
# but we keep this around for libraries that directly require it knowing they
|
|
5
|
+
# want cattr_*. No need to deprecate.
|
|
6
|
+
require "active_support/core_ext/module/attribute_accessors"
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Class
|
|
4
|
+
begin
|
|
5
|
+
# Test if this Ruby supports each_object against singleton_class
|
|
6
|
+
ObjectSpace.each_object(Numeric.singleton_class) { }
|
|
7
|
+
|
|
8
|
+
# Returns an array with all classes that are < than its receiver.
|
|
9
|
+
#
|
|
10
|
+
# class C; end
|
|
11
|
+
# C.descendants # => []
|
|
12
|
+
#
|
|
13
|
+
# class B < C; end
|
|
14
|
+
# C.descendants # => [B]
|
|
15
|
+
#
|
|
16
|
+
# class A < B; end
|
|
17
|
+
# C.descendants # => [B, A]
|
|
18
|
+
#
|
|
19
|
+
# class D < C; end
|
|
20
|
+
# C.descendants # => [B, A, D]
|
|
21
|
+
def descendants
|
|
22
|
+
descendants = []
|
|
23
|
+
ObjectSpace.each_object(singleton_class) do |k|
|
|
24
|
+
next if k.singleton_class?
|
|
25
|
+
descendants.unshift k unless k == self
|
|
26
|
+
end
|
|
27
|
+
descendants
|
|
28
|
+
end
|
|
29
|
+
rescue StandardError # JRuby 9.0.4.0 and earlier
|
|
30
|
+
def descendants
|
|
31
|
+
descendants = []
|
|
32
|
+
ObjectSpace.each_object(Class) do |k|
|
|
33
|
+
descendants.unshift k if k < self
|
|
34
|
+
end
|
|
35
|
+
descendants.uniq!
|
|
36
|
+
descendants
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Returns an array with the direct children of +self+.
|
|
41
|
+
#
|
|
42
|
+
# class Foo; end
|
|
43
|
+
# class Bar < Foo; end
|
|
44
|
+
# class Baz < Bar; end
|
|
45
|
+
#
|
|
46
|
+
# Foo.subclasses # => [Bar]
|
|
47
|
+
def subclasses
|
|
48
|
+
subclasses, chain = [], descendants
|
|
49
|
+
chain.each do |k|
|
|
50
|
+
subclasses << k unless chain.any? { |c| c > k }
|
|
51
|
+
end
|
|
52
|
+
subclasses
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_support/core_ext/date/acts_like"
|
|
4
|
+
require "active_support/core_ext/date/blank"
|
|
5
|
+
require "active_support/core_ext/date/calculations"
|
|
6
|
+
require "active_support/core_ext/date/conversions"
|
|
7
|
+
require "active_support/core_ext/date/zones"
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "date"
|
|
4
|
+
require "active_support/duration"
|
|
5
|
+
require "active_support/core_ext/object/acts_like"
|
|
6
|
+
require "active_support/core_ext/date/zones"
|
|
7
|
+
require "active_support/core_ext/time/zones"
|
|
8
|
+
require "active_support/core_ext/date_and_time/calculations"
|
|
9
|
+
|
|
10
|
+
class Date
|
|
11
|
+
include DateAndTime::Calculations
|
|
12
|
+
|
|
13
|
+
class << self
|
|
14
|
+
attr_accessor :beginning_of_week_default
|
|
15
|
+
|
|
16
|
+
# Returns the week start (e.g. :monday) for the current request, if this has been set (via Date.beginning_of_week=).
|
|
17
|
+
# If <tt>Date.beginning_of_week</tt> has not been set for the current request, returns the week start specified in <tt>config.beginning_of_week</tt>.
|
|
18
|
+
# If no config.beginning_of_week was specified, returns :monday.
|
|
19
|
+
def beginning_of_week
|
|
20
|
+
Thread.current[:beginning_of_week] || beginning_of_week_default || :monday
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Sets <tt>Date.beginning_of_week</tt> to a week start (e.g. :monday) for current request/thread.
|
|
24
|
+
#
|
|
25
|
+
# This method accepts any of the following day symbols:
|
|
26
|
+
# :monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday
|
|
27
|
+
def beginning_of_week=(week_start)
|
|
28
|
+
Thread.current[:beginning_of_week] = find_beginning_of_week!(week_start)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Returns week start day symbol (e.g. :monday), or raises an +ArgumentError+ for invalid day symbol.
|
|
32
|
+
def find_beginning_of_week!(week_start)
|
|
33
|
+
raise ArgumentError, "Invalid beginning of week: #{week_start}" unless ::Date::DAYS_INTO_WEEK.key?(week_start)
|
|
34
|
+
week_start
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Returns a new Date representing the date 1 day ago (i.e. yesterday's date).
|
|
38
|
+
def yesterday
|
|
39
|
+
::Date.current.yesterday
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Returns a new Date representing the date 1 day after today (i.e. tomorrow's date).
|
|
43
|
+
def tomorrow
|
|
44
|
+
::Date.current.tomorrow
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Returns Time.zone.today when <tt>Time.zone</tt> or <tt>config.time_zone</tt> are set, otherwise just returns Date.today.
|
|
48
|
+
def current
|
|
49
|
+
::Time.zone ? ::Time.zone.today : ::Date.today
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
|
|
54
|
+
# and then subtracts the specified number of seconds.
|
|
55
|
+
def ago(seconds)
|
|
56
|
+
in_time_zone.since(-seconds)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
|
|
60
|
+
# and then adds the specified number of seconds
|
|
61
|
+
def since(seconds)
|
|
62
|
+
in_time_zone.since(seconds)
|
|
63
|
+
end
|
|
64
|
+
alias :in :since
|
|
65
|
+
|
|
66
|
+
# Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
|
|
67
|
+
def beginning_of_day
|
|
68
|
+
in_time_zone
|
|
69
|
+
end
|
|
70
|
+
alias :midnight :beginning_of_day
|
|
71
|
+
alias :at_midnight :beginning_of_day
|
|
72
|
+
alias :at_beginning_of_day :beginning_of_day
|
|
73
|
+
|
|
74
|
+
# Converts Date to a Time (or DateTime if necessary) with the time portion set to the middle of the day (12:00)
|
|
75
|
+
def middle_of_day
|
|
76
|
+
in_time_zone.middle_of_day
|
|
77
|
+
end
|
|
78
|
+
alias :midday :middle_of_day
|
|
79
|
+
alias :noon :middle_of_day
|
|
80
|
+
alias :at_midday :middle_of_day
|
|
81
|
+
alias :at_noon :middle_of_day
|
|
82
|
+
alias :at_middle_of_day :middle_of_day
|
|
83
|
+
|
|
84
|
+
# Converts Date to a Time (or DateTime if necessary) with the time portion set to the end of the day (23:59:59)
|
|
85
|
+
def end_of_day
|
|
86
|
+
in_time_zone.end_of_day
|
|
87
|
+
end
|
|
88
|
+
alias :at_end_of_day :end_of_day
|
|
89
|
+
|
|
90
|
+
def plus_with_duration(other) #:nodoc:
|
|
91
|
+
if ActiveSupport::Duration === other
|
|
92
|
+
other.since(self)
|
|
93
|
+
else
|
|
94
|
+
plus_without_duration(other)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
alias_method :plus_without_duration, :+
|
|
98
|
+
alias_method :+, :plus_with_duration
|
|
99
|
+
|
|
100
|
+
def minus_with_duration(other) #:nodoc:
|
|
101
|
+
if ActiveSupport::Duration === other
|
|
102
|
+
plus_with_duration(-other)
|
|
103
|
+
else
|
|
104
|
+
minus_without_duration(other)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
alias_method :minus_without_duration, :-
|
|
108
|
+
alias_method :-, :minus_with_duration
|
|
109
|
+
|
|
110
|
+
# Provides precise Date calculations for years, months, and days. The +options+ parameter takes a hash with
|
|
111
|
+
# any of these keys: <tt>:years</tt>, <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>.
|
|
112
|
+
def advance(options)
|
|
113
|
+
d = self
|
|
114
|
+
|
|
115
|
+
d = d >> options[:years] * 12 if options[:years]
|
|
116
|
+
d = d >> options[:months] if options[:months]
|
|
117
|
+
d = d + options[:weeks] * 7 if options[:weeks]
|
|
118
|
+
d = d + options[:days] if options[:days]
|
|
119
|
+
|
|
120
|
+
d
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Returns a new Date where one or more of the elements have been changed according to the +options+ parameter.
|
|
124
|
+
# The +options+ parameter is a hash with a combination of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>.
|
|
125
|
+
#
|
|
126
|
+
# Date.new(2007, 5, 12).change(day: 1) # => Date.new(2007, 5, 1)
|
|
127
|
+
# Date.new(2007, 5, 12).change(year: 2005, month: 1) # => Date.new(2005, 1, 12)
|
|
128
|
+
def change(options)
|
|
129
|
+
::Date.new(
|
|
130
|
+
options.fetch(:year, year),
|
|
131
|
+
options.fetch(:month, month),
|
|
132
|
+
options.fetch(:day, day)
|
|
133
|
+
)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Allow Date to be compared with Time by converting to DateTime and relying on the <=> from there.
|
|
137
|
+
def compare_with_coercion(other)
|
|
138
|
+
if other.is_a?(Time)
|
|
139
|
+
to_datetime <=> other
|
|
140
|
+
else
|
|
141
|
+
compare_without_coercion(other)
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
alias_method :compare_without_coercion, :<=>
|
|
145
|
+
alias_method :<=>, :compare_with_coercion
|
|
146
|
+
end
|