activesupport 4.0.13 → 5.2.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +412 -444
- data/MIT-LICENSE +2 -2
- data/README.rdoc +8 -4
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +14 -12
- data/lib/active_support/benchmarkable.rb +6 -14
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache/file_store.rb +67 -51
- data/lib/active_support/cache/mem_cache_store.rb +95 -97
- data/lib/active_support/cache/memory_store.rb +28 -30
- data/lib/active_support/cache/null_store.rb +7 -8
- data/lib/active_support/cache/redis_cache_store.rb +466 -0
- data/lib/active_support/cache/strategy/local_cache.rb +70 -56
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
- data/lib/active_support/cache.rb +331 -206
- data/lib/active_support/callbacks.rb +697 -426
- data/lib/active_support/concern.rb +32 -10
- 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 +8 -5
- data/lib/active_support/core_ext/array/access.rb +39 -1
- data/lib/active_support/core_ext/array/conversions.rb +24 -35
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +23 -13
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +7 -5
- data/lib/active_support/core_ext/array/wrap.rb +7 -4
- data/lib/active_support/core_ext/array.rb +9 -7
- data/lib/active_support/core_ext/benchmark.rb +3 -1
- data/lib/active_support/core_ext/big_decimal/conversions.rb +9 -26
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/class/attribute.rb +41 -23
- data/lib/active_support/core_ext/class/attribute_accessors.rb +5 -169
- data/lib/active_support/core_ext/class/subclasses.rb +20 -8
- data/lib/active_support/core_ext/class.rb +4 -4
- data/lib/active_support/core_ext/date/acts_like.rb +3 -1
- data/lib/active_support/core_ext/date/blank.rb +14 -0
- data/lib/active_support/core_ext/date/calculations.rb +21 -9
- data/lib/active_support/core_ext/date/conversions.rb +32 -22
- data/lib/active_support/core_ext/date/zones.rb +5 -34
- data/lib/active_support/core_ext/date.rb +6 -4
- data/lib/active_support/core_ext/date_and_time/calculations.rb +199 -57
- 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/acts_like.rb +4 -2
- data/lib/active_support/core_ext/date_time/blank.rb +14 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +78 -37
- data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +19 -13
- data/lib/active_support/core_ext/date_time.rb +7 -4
- data/lib/active_support/core_ext/digest/uuid.rb +53 -0
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +113 -29
- data/lib/active_support/core_ext/file/atomic.rb +38 -31
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/hash/compact.rb +29 -0
- data/lib/active_support/core_ext/hash/conversions.rb +71 -49
- data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
- data/lib/active_support/core_ext/hash/except.rb +12 -3
- data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
- data/lib/active_support/core_ext/hash/keys.rb +50 -38
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +12 -6
- data/lib/active_support/core_ext/hash/transform_values.rb +32 -0
- data/lib/active_support/core_ext/hash.rb +11 -8
- data/lib/active_support/core_ext/integer/inflections.rb +3 -1
- data/lib/active_support/core_ext/integer/multiple.rb +2 -0
- data/lib/active_support/core_ext/integer/time.rb +11 -33
- data/lib/active_support/core_ext/integer.rb +5 -3
- data/lib/active_support/core_ext/kernel/agnostics.rb +2 -0
- data/lib/active_support/core_ext/kernel/concern.rb +14 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +5 -74
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +6 -4
- data/lib/active_support/core_ext/load_error.rb +5 -21
- data/lib/active_support/core_ext/marshal.rb +13 -10
- data/lib/active_support/core_ext/module/aliasing.rb +6 -44
- data/lib/active_support/core_ext/module/anonymous.rb +12 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +8 -8
- data/lib/active_support/core_ext/module/attribute_accessors.rb +170 -21
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +150 -0
- data/lib/active_support/core_ext/module/concerning.rb +134 -0
- data/lib/active_support/core_ext/module/delegation.rb +135 -45
- data/lib/active_support/core_ext/module/deprecation.rb +3 -3
- data/lib/active_support/core_ext/module/introspection.rb +9 -25
- data/lib/active_support/core_ext/module/reachable.rb +5 -2
- data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
- data/lib/active_support/core_ext/module/remove_method.rb +8 -3
- data/lib/active_support/core_ext/module.rb +14 -10
- data/lib/active_support/core_ext/name_error.rb +22 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +79 -74
- data/lib/active_support/core_ext/numeric/inquiry.rb +28 -0
- data/lib/active_support/core_ext/numeric/time.rb +37 -50
- data/lib/active_support/core_ext/numeric.rb +6 -3
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +70 -19
- data/lib/active_support/core_ext/object/conversions.rb +6 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +19 -10
- data/lib/active_support/core_ext/object/duplicable.rb +100 -34
- data/lib/active_support/core_ext/object/inclusion.rb +18 -15
- data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
- data/lib/active_support/core_ext/object/json.rb +227 -0
- data/lib/active_support/core_ext/object/to_param.rb +3 -1
- data/lib/active_support/core_ext/object/to_query.rb +21 -8
- data/lib/active_support/core_ext/object/try.rb +94 -24
- data/lib/active_support/core_ext/object/with_options.rb +45 -5
- data/lib/active_support/core_ext/object.rb +14 -12
- data/lib/active_support/core_ext/range/compare_range.rb +61 -0
- data/lib/active_support/core_ext/range/conversions.rb +27 -7
- data/lib/active_support/core_ext/range/each.rb +19 -17
- data/lib/active_support/core_ext/range/include_range.rb +2 -22
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
- data/lib/active_support/core_ext/range/overlaps.rb +2 -0
- data/lib/active_support/core_ext/range.rb +7 -4
- data/lib/active_support/core_ext/regexp.rb +6 -0
- data/lib/active_support/core_ext/securerandom.rb +25 -0
- data/lib/active_support/core_ext/string/access.rb +41 -39
- data/lib/active_support/core_ext/string/behavior.rb +3 -1
- data/lib/active_support/core_ext/string/conversions.rb +17 -13
- data/lib/active_support/core_ext/string/exclude.rb +5 -3
- data/lib/active_support/core_ext/string/filters.rb +55 -6
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +66 -24
- data/lib/active_support/core_ext/string/inquiry.rb +3 -1
- data/lib/active_support/core_ext/string/multibyte.rb +15 -7
- data/lib/active_support/core_ext/string/output_safety.rb +114 -54
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
- data/lib/active_support/core_ext/string/strip.rb +4 -5
- data/lib/active_support/core_ext/string/zones.rb +4 -1
- data/lib/active_support/core_ext/string.rb +15 -13
- data/lib/active_support/core_ext/time/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +123 -110
- data/lib/active_support/core_ext/time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/time/conversions.rb +23 -14
- data/lib/active_support/core_ext/time/zones.rb +42 -26
- data/lib/active_support/core_ext/time.rb +7 -5
- data/lib/active_support/core_ext/uri.rb +6 -8
- data/lib/active_support/core_ext.rb +3 -2
- data/lib/active_support/current_attributes.rb +195 -0
- data/lib/active_support/dependencies/autoload.rb +3 -1
- data/lib/active_support/dependencies/interlock.rb +57 -0
- data/lib/active_support/dependencies.rb +196 -166
- data/lib/active_support/deprecation/behaviors.rb +48 -15
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/instance_delegator.rb +17 -2
- data/lib/active_support/deprecation/method_wrappers.rb +66 -20
- data/lib/active_support/deprecation/proxy_wrappers.rb +56 -28
- data/lib/active_support/deprecation/reporting.rb +32 -12
- data/lib/active_support/deprecation.rb +14 -11
- data/lib/active_support/descendants_tracker.rb +2 -0
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration/iso8601_parser.rb +125 -0
- data/lib/active_support/duration/iso8601_serializer.rb +55 -0
- data/lib/active_support/duration.rb +354 -34
- data/lib/active_support/encrypted_configuration.rb +49 -0
- data/lib/active_support/encrypted_file.rb +99 -0
- data/lib/active_support/evented_file_update_checker.rb +205 -0
- data/lib/active_support/execution_wrapper.rb +128 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +63 -37
- data/lib/active_support/gem_version.rb +17 -0
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +158 -35
- data/lib/active_support/i18n.rb +8 -6
- data/lib/active_support/i18n_railtie.rb +38 -20
- data/lib/active_support/inflections.rb +19 -12
- data/lib/active_support/inflector/inflections.rb +79 -30
- data/lib/active_support/inflector/methods.rb +197 -129
- data/lib/active_support/inflector/transliterate.rb +48 -27
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/json/decoding.rb +21 -25
- data/lib/active_support/json/encoding.rb +84 -292
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/key_generator.rb +26 -28
- data/lib/active_support/lazy_load_hooks.rb +51 -21
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber/test_helper.rb +14 -12
- data/lib/active_support/log_subscriber.rb +13 -10
- data/lib/active_support/logger.rb +54 -3
- data/lib/active_support/logger_silence.rb +12 -7
- data/lib/active_support/logger_thread_safe_level.rb +34 -0
- data/lib/active_support/message_encryptor.rb +173 -50
- data/lib/active_support/message_verifier.rb +159 -22
- 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/chars.rb +38 -26
- data/lib/active_support/multibyte/unicode.rb +138 -146
- data/lib/active_support/multibyte.rb +4 -2
- data/lib/active_support/notifications/fanout.rb +23 -16
- data/lib/active_support/notifications/instrumenter.rb +29 -8
- data/lib/active_support/notifications.rb +22 -13
- 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 +29 -0
- data/lib/active_support/number_helper/number_to_human_converter.rb +68 -0
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +59 -0
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +14 -0
- data/lib/active_support/number_helper/number_to_phone_converter.rb +58 -0
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +54 -0
- data/lib/active_support/number_helper/rounding_helper.rb +66 -0
- data/lib/active_support/number_helper.rb +125 -391
- data/lib/active_support/option_merger.rb +3 -1
- data/lib/active_support/ordered_hash.rb +6 -4
- data/lib/active_support/ordered_options.rb +31 -5
- data/lib/active_support/per_thread_registry.rb +19 -11
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +16 -8
- data/lib/active_support/railtie.rb +43 -9
- data/lib/active_support/reloader.rb +131 -0
- data/lib/active_support/rescuable.rb +108 -53
- data/lib/active_support/security_utils.rb +31 -0
- data/lib/active_support/string_inquirer.rb +11 -3
- data/lib/active_support/subscriber.rb +54 -17
- data/lib/active_support/tagged_logging.rb +14 -11
- data/lib/active_support/test_case.rb +42 -37
- data/lib/active_support/testing/assertions.rb +126 -39
- data/lib/active_support/testing/autorun.rb +5 -3
- data/lib/active_support/testing/constant_lookup.rb +3 -6
- data/lib/active_support/testing/declarative.rb +10 -22
- data/lib/active_support/testing/deprecation.rb +14 -10
- data/lib/active_support/testing/file_fixtures.rb +36 -0
- data/lib/active_support/testing/isolation.rb +55 -86
- data/lib/active_support/testing/method_call_assertions.rb +43 -0
- data/lib/active_support/testing/setup_and_teardown.rb +30 -10
- data/lib/active_support/testing/stream.rb +44 -0
- data/lib/active_support/testing/tagged_logging.rb +5 -3
- data/lib/active_support/testing/time_helpers.rb +200 -0
- data/lib/active_support/time.rb +13 -13
- data/lib/active_support/time_with_zone.rb +223 -73
- data/lib/active_support/values/time_zone.rb +261 -126
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +6 -7
- data/lib/active_support/xml_mini/jdom.rb +116 -113
- data/lib/active_support/xml_mini/libxml.rb +17 -16
- data/lib/active_support/xml_mini/libxmlsax.rb +16 -18
- data/lib/active_support/xml_mini/nokogiri.rb +15 -15
- data/lib/active_support/xml_mini/nokogirisax.rb +15 -16
- data/lib/active_support/xml_mini/rexml.rb +17 -16
- data/lib/active_support/xml_mini.rb +69 -51
- data/lib/active_support.rb +29 -3
- metadata +84 -54
- data/lib/active_support/basic_object.rb +0 -11
- data/lib/active_support/buffered_logger.rb +0 -21
- data/lib/active_support/concurrency/latch.rb +0 -27
- data/lib/active_support/core_ext/array/uniq_by.rb +0 -19
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -40
- data/lib/active_support/core_ext/date_time/zones.rb +0 -24
- data/lib/active_support/core_ext/hash/diff.rb +0 -14
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
- data/lib/active_support/core_ext/logger.rb +0 -67
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
- data/lib/active_support/core_ext/object/to_json.rb +0 -27
- data/lib/active_support/core_ext/proc.rb +0 -17
- data/lib/active_support/core_ext/string/encoding.rb +0 -8
- data/lib/active_support/core_ext/struct.rb +0 -6
- data/lib/active_support/core_ext/thread.rb +0 -79
- data/lib/active_support/core_ext/time/marshal.rb +0 -30
- data/lib/active_support/file_watcher.rb +0 -36
- data/lib/active_support/json/variable.rb +0 -18
- data/lib/active_support/testing/pending.rb +0 -14
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/date_and_time/compatibility"
|
4
|
+
require "active_support/core_ext/module/redefine_method"
|
5
|
+
|
6
|
+
class DateTime
|
7
|
+
include DateAndTime::Compatibility
|
8
|
+
|
9
|
+
silence_redefinition_of_method :to_time
|
10
|
+
|
11
|
+
# Either return an instance of +Time+ with the same UTC offset
|
12
|
+
# as +self+ or an instance of +Time+ representing the same time
|
13
|
+
# in the local system timezone depending on the setting of
|
14
|
+
# on the setting of +ActiveSupport.to_time_preserves_timezone+.
|
15
|
+
def to_time
|
16
|
+
preserve_timezone ? getlocal(utc_offset) : getlocal
|
17
|
+
end
|
18
|
+
end
|
@@ -1,7 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "date"
|
4
|
+
require "active_support/inflector/methods"
|
5
|
+
require "active_support/core_ext/time/conversions"
|
6
|
+
require "active_support/core_ext/date_time/calculations"
|
7
|
+
require "active_support/values/time_zone"
|
5
8
|
|
6
9
|
class DateTime
|
7
10
|
# Convert to a formatted string. See Time::DATE_FORMATS for predefined formats.
|
@@ -18,6 +21,7 @@ class DateTime
|
|
18
21
|
# datetime.to_formatted_s(:long) # => "December 04, 2007 00:00"
|
19
22
|
# datetime.to_formatted_s(:long_ordinal) # => "December 4th, 2007 00:00"
|
20
23
|
# datetime.to_formatted_s(:rfc822) # => "Tue, 04 Dec 2007 00:00:00 +0000"
|
24
|
+
# datetime.to_formatted_s(:iso8601) # => "2007-12-04T00:00:00+00:00"
|
21
25
|
#
|
22
26
|
# == Adding your own datetime formats to to_formatted_s
|
23
27
|
# DateTime formats are shared with Time. You can add your own to the
|
@@ -38,6 +42,8 @@ class DateTime
|
|
38
42
|
alias_method :to_default_s, :to_s if instance_methods(false).include?(:to_s)
|
39
43
|
alias_method :to_s, :to_formatted_s
|
40
44
|
|
45
|
+
# Returns a formatted string of the offset from UTC, or an alternative
|
46
|
+
# string if the time zone is already UTC.
|
41
47
|
#
|
42
48
|
# datetime = DateTime.civil(2000, 1, 1, 0, 0, 0, Rational(-6, 24))
|
43
49
|
# datetime.formatted_offset # => "-06:00"
|
@@ -60,7 +66,7 @@ class DateTime
|
|
60
66
|
# # => Sun, 01 Jan 2012 00:00:00 +0300
|
61
67
|
# DateTime.civil_from_format :local, 2012, 12, 17
|
62
68
|
# # => Mon, 17 Dec 2012 00:00:00 +0000
|
63
|
-
def self.civil_from_format(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0)
|
69
|
+
def self.civil_from_format(utc_or_local, year, month = 1, day = 1, hour = 0, min = 0, sec = 0)
|
64
70
|
if utc_or_local.to_sym == :local
|
65
71
|
offset = ::Time.local(year, month, day).utc_offset.to_r / 86400
|
66
72
|
else
|
@@ -69,9 +75,9 @@ class DateTime
|
|
69
75
|
civil(year, month, day, hour, min, sec, offset)
|
70
76
|
end
|
71
77
|
|
72
|
-
# Converts +self+ to a floating-point number of seconds since the Unix epoch.
|
78
|
+
# Converts +self+ to a floating-point number of seconds, including fractional microseconds, since the Unix epoch.
|
73
79
|
def to_f
|
74
|
-
seconds_since_unix_epoch.to_f
|
80
|
+
seconds_since_unix_epoch.to_f + sec_fraction
|
75
81
|
end
|
76
82
|
|
77
83
|
# Converts +self+ to an integer number of seconds since the Unix epoch.
|
@@ -91,11 +97,11 @@ class DateTime
|
|
91
97
|
|
92
98
|
private
|
93
99
|
|
94
|
-
|
95
|
-
|
96
|
-
|
100
|
+
def offset_in_seconds
|
101
|
+
(offset * 86400).to_i
|
102
|
+
end
|
97
103
|
|
98
|
-
|
99
|
-
|
100
|
-
|
104
|
+
def seconds_since_unix_epoch
|
105
|
+
(jd - 2440588) * 86400 - offset_in_seconds + seconds_since_midnight
|
106
|
+
end
|
101
107
|
end
|
@@ -1,4 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/date_time/acts_like"
|
4
|
+
require "active_support/core_ext/date_time/blank"
|
5
|
+
require "active_support/core_ext/date_time/calculations"
|
6
|
+
require "active_support/core_ext/date_time/compatibility"
|
7
|
+
require "active_support/core_ext/date_time/conversions"
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "securerandom"
|
4
|
+
|
5
|
+
module Digest
|
6
|
+
module UUID
|
7
|
+
DNS_NAMESPACE = "k\xA7\xB8\x10\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
|
8
|
+
URL_NAMESPACE = "k\xA7\xB8\x11\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
|
9
|
+
OID_NAMESPACE = "k\xA7\xB8\x12\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
|
10
|
+
X500_NAMESPACE = "k\xA7\xB8\x14\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
|
11
|
+
|
12
|
+
# Generates a v5 non-random UUID (Universally Unique IDentifier).
|
13
|
+
#
|
14
|
+
# Using Digest::MD5 generates version 3 UUIDs; Digest::SHA1 generates version 5 UUIDs.
|
15
|
+
# uuid_from_hash always generates the same UUID for a given name and namespace combination.
|
16
|
+
#
|
17
|
+
# See RFC 4122 for details of UUID at: https://www.ietf.org/rfc/rfc4122.txt
|
18
|
+
def self.uuid_from_hash(hash_class, uuid_namespace, name)
|
19
|
+
if hash_class == Digest::MD5
|
20
|
+
version = 3
|
21
|
+
elsif hash_class == Digest::SHA1
|
22
|
+
version = 5
|
23
|
+
else
|
24
|
+
raise ArgumentError, "Expected Digest::SHA1 or Digest::MD5, got #{hash_class.name}."
|
25
|
+
end
|
26
|
+
|
27
|
+
hash = hash_class.new
|
28
|
+
hash.update(uuid_namespace)
|
29
|
+
hash.update(name)
|
30
|
+
|
31
|
+
ary = hash.digest.unpack("NnnnnN")
|
32
|
+
ary[2] = (ary[2] & 0x0FFF) | (version << 12)
|
33
|
+
ary[3] = (ary[3] & 0x3FFF) | 0x8000
|
34
|
+
|
35
|
+
"%08x-%04x-%04x-%04x-%04x%08x" % ary
|
36
|
+
end
|
37
|
+
|
38
|
+
# Convenience method for uuid_from_hash using Digest::MD5.
|
39
|
+
def self.uuid_v3(uuid_namespace, name)
|
40
|
+
uuid_from_hash(Digest::MD5, uuid_namespace, name)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Convenience method for uuid_from_hash using Digest::SHA1.
|
44
|
+
def self.uuid_v5(uuid_namespace, name)
|
45
|
+
uuid_from_hash(Digest::SHA1, uuid_namespace, name)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Convenience method for SecureRandom.uuid.
|
49
|
+
def self.uuid_v4
|
50
|
+
SecureRandom.uuid
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -1,41 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Enumerable
|
2
|
-
#
|
3
|
-
#
|
4
|
-
# payments.sum { |p| p.price * p.tax_rate }
|
5
|
-
# payments.sum(&:price)
|
6
|
-
#
|
7
|
-
# The latter is a shortcut for:
|
8
|
-
#
|
9
|
-
# payments.inject(0) { |sum, p| sum + p.price }
|
10
|
-
#
|
11
|
-
# It can also calculate the sum without the use of a block.
|
4
|
+
# Enumerable#sum was added in Ruby 2.4, but it only works with Numeric elements
|
5
|
+
# when we omit an identity.
|
12
6
|
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
7
|
+
# We tried shimming it to attempt the fast native method, rescue TypeError,
|
8
|
+
# and fall back to the compatible implementation, but that's much slower than
|
9
|
+
# just calling the compat method in the first place.
|
10
|
+
if Enumerable.instance_methods(false).include?(:sum) && !((?a..?b).sum rescue false)
|
11
|
+
# :stopdoc:
|
12
|
+
|
13
|
+
# We can't use Refinements here because Refinements with Module which will be prepended
|
14
|
+
# doesn't work well https://bugs.ruby-lang.org/issues/13446
|
15
|
+
alias :_original_sum_with_required_identity :sum
|
16
|
+
private :_original_sum_with_required_identity
|
17
|
+
|
18
|
+
# :startdoc:
|
19
|
+
|
20
|
+
# Calculates a sum from the elements.
|
21
|
+
#
|
22
|
+
# payments.sum { |p| p.price * p.tax_rate }
|
23
|
+
# payments.sum(&:price)
|
24
|
+
#
|
25
|
+
# The latter is a shortcut for:
|
26
|
+
#
|
27
|
+
# payments.inject(0) { |sum, p| sum + p.price }
|
28
|
+
#
|
29
|
+
# It can also calculate the sum without the use of a block.
|
30
|
+
#
|
31
|
+
# [5, 15, 10].sum # => 30
|
32
|
+
# ['foo', 'bar'].sum # => "foobar"
|
33
|
+
# [[1, 2], [3, 1, 5]].sum # => [1, 2, 3, 1, 5]
|
34
|
+
#
|
35
|
+
# The default sum of an empty list is zero. You can override this default:
|
36
|
+
#
|
37
|
+
# [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
|
38
|
+
def sum(identity = nil, &block)
|
39
|
+
if identity
|
40
|
+
_original_sum_with_required_identity(identity, &block)
|
41
|
+
elsif block_given?
|
42
|
+
map(&block).sum(identity)
|
43
|
+
else
|
44
|
+
inject(:+) || 0
|
45
|
+
end
|
46
|
+
end
|
47
|
+
else
|
48
|
+
def sum(identity = nil, &block)
|
49
|
+
if block_given?
|
50
|
+
map(&block).sum(identity)
|
51
|
+
else
|
52
|
+
sum = identity ? inject(identity, :+) : inject(:+)
|
53
|
+
sum || identity || 0
|
54
|
+
end
|
25
55
|
end
|
26
56
|
end
|
27
57
|
|
28
58
|
# Convert an enumerable to a hash.
|
29
59
|
#
|
30
60
|
# people.index_by(&:login)
|
31
|
-
#
|
61
|
+
# # => { "nextangle" => <Person ...>, "chade-" => <Person ...>, ...}
|
32
62
|
# people.index_by { |person| "#{person.first_name} #{person.last_name}" }
|
33
|
-
#
|
63
|
+
# # => { "Chade- Fowlersburg-e" => <Person ...>, "David Heinemeier Hansson" => <Person ...>, ...}
|
34
64
|
def index_by
|
35
65
|
if block_given?
|
36
|
-
|
66
|
+
result = {}
|
67
|
+
each { |elem| result[yield(elem)] = elem }
|
68
|
+
result
|
37
69
|
else
|
38
|
-
to_enum :
|
70
|
+
to_enum(:index_by) { size if respond_to?(:size) }
|
39
71
|
end
|
40
72
|
end
|
41
73
|
|
@@ -60,20 +92,72 @@ module Enumerable
|
|
60
92
|
def exclude?(object)
|
61
93
|
!include?(object)
|
62
94
|
end
|
95
|
+
|
96
|
+
# Returns a copy of the enumerable without the specified elements.
|
97
|
+
#
|
98
|
+
# ["David", "Rafael", "Aaron", "Todd"].without "Aaron", "Todd"
|
99
|
+
# # => ["David", "Rafael"]
|
100
|
+
#
|
101
|
+
# {foo: 1, bar: 2, baz: 3}.without :bar
|
102
|
+
# # => {foo: 1, baz: 3}
|
103
|
+
def without(*elements)
|
104
|
+
reject { |element| elements.include?(element) }
|
105
|
+
end
|
106
|
+
|
107
|
+
# Convert an enumerable to an array based on the given key.
|
108
|
+
#
|
109
|
+
# [{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pluck(:name)
|
110
|
+
# # => ["David", "Rafael", "Aaron"]
|
111
|
+
#
|
112
|
+
# [{ id: 1, name: "David" }, { id: 2, name: "Rafael" }].pluck(:id, :name)
|
113
|
+
# # => [[1, "David"], [2, "Rafael"]]
|
114
|
+
def pluck(*keys)
|
115
|
+
if keys.many?
|
116
|
+
map { |element| keys.map { |key| element[key] } }
|
117
|
+
else
|
118
|
+
map { |element| element[keys.first] }
|
119
|
+
end
|
120
|
+
end
|
63
121
|
end
|
64
122
|
|
65
123
|
class Range #:nodoc:
|
66
124
|
# Optimize range sum to use arithmetic progression if a block is not given and
|
67
125
|
# we have a range of numeric values.
|
68
|
-
def sum(identity =
|
126
|
+
def sum(identity = nil)
|
69
127
|
if block_given? || !(first.is_a?(Integer) && last.is_a?(Integer))
|
70
128
|
super
|
71
129
|
else
|
72
130
|
actual_last = exclude_end? ? (last - 1) : last
|
73
131
|
if actual_last >= first
|
74
|
-
|
132
|
+
sum = identity || 0
|
133
|
+
sum + (actual_last - first + 1) * (actual_last + first) / 2
|
134
|
+
else
|
135
|
+
identity || 0
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# Array#sum was added in Ruby 2.4 but it only works with Numeric elements.
|
142
|
+
#
|
143
|
+
# We tried shimming it to attempt the fast native method, rescue TypeError,
|
144
|
+
# and fall back to the compatible implementation, but that's much slower than
|
145
|
+
# just calling the compat method in the first place.
|
146
|
+
if Array.instance_methods(false).include?(:sum) && !(%w[a].sum rescue false)
|
147
|
+
# Using Refinements here in order not to expose our internal method
|
148
|
+
using Module.new {
|
149
|
+
refine Array do
|
150
|
+
alias :orig_sum :sum
|
151
|
+
end
|
152
|
+
}
|
153
|
+
|
154
|
+
class Array
|
155
|
+
def sum(init = nil, &block) #:nodoc:
|
156
|
+
if init.is_a?(Numeric) || first.is_a?(Numeric)
|
157
|
+
init ||= 0
|
158
|
+
orig_sum(init, &block)
|
75
159
|
else
|
76
|
-
|
160
|
+
super
|
77
161
|
end
|
78
162
|
end
|
79
163
|
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "fileutils"
|
2
4
|
|
3
5
|
class File
|
4
6
|
# Write to a file atomically. Useful for situations where you don't
|
@@ -8,51 +10,56 @@ class File
|
|
8
10
|
# file.write('hello')
|
9
11
|
# end
|
10
12
|
#
|
11
|
-
#
|
12
|
-
#
|
13
|
+
# This method needs to create a temporary file. By default it will create it
|
14
|
+
# in the same directory as the destination file. If you don't like this
|
15
|
+
# behavior you can provide a different directory but it must be on the
|
16
|
+
# same physical filesystem as the file you're trying to write.
|
13
17
|
#
|
14
18
|
# File.atomic_write('/data/something.important', '/data/tmp') do |file|
|
15
19
|
# file.write('hello')
|
16
20
|
# end
|
17
|
-
def self.atomic_write(file_name, temp_dir =
|
18
|
-
require
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
end
|
21
|
+
def self.atomic_write(file_name, temp_dir = dirname(file_name))
|
22
|
+
require "tempfile" unless defined?(Tempfile)
|
23
|
+
|
24
|
+
Tempfile.open(".#{basename(file_name)}", temp_dir) do |temp_file|
|
25
|
+
temp_file.binmode
|
26
|
+
return_val = yield temp_file
|
27
|
+
temp_file.close
|
28
|
+
|
29
|
+
old_stat = if exist?(file_name)
|
30
|
+
# Get original file permissions
|
31
|
+
stat(file_name)
|
32
|
+
else
|
33
|
+
# If not possible, probe which are the default permissions in the
|
34
|
+
# destination directory.
|
35
|
+
probe_stat_in(dirname(file_name))
|
36
|
+
end
|
34
37
|
|
35
|
-
|
36
|
-
|
38
|
+
if old_stat
|
39
|
+
# Set correct permissions on new file
|
40
|
+
begin
|
41
|
+
chown(old_stat.uid, old_stat.gid, temp_file.path)
|
42
|
+
# This operation will affect filesystem ACL's
|
43
|
+
chmod(old_stat.mode, temp_file.path)
|
44
|
+
rescue Errno::EPERM, Errno::EACCES
|
45
|
+
# Changing file ownership failed, moving on.
|
46
|
+
end
|
47
|
+
end
|
37
48
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
# This operation will affect filesystem ACL's
|
42
|
-
chmod(old_stat.mode, file_name)
|
43
|
-
rescue Errno::EPERM
|
44
|
-
# Changing file ownership failed, moving on.
|
49
|
+
# Overwrite original file with temp file
|
50
|
+
rename(temp_file.path, file_name)
|
51
|
+
return_val
|
45
52
|
end
|
46
53
|
end
|
47
54
|
|
48
55
|
# Private utility method.
|
49
56
|
def self.probe_stat_in(dir) #:nodoc:
|
50
57
|
basename = [
|
51
|
-
|
58
|
+
".permissions_check",
|
52
59
|
Thread.current.object_id,
|
53
60
|
Process.pid,
|
54
61
|
rand(1000000)
|
55
|
-
].join(
|
62
|
+
].join(".")
|
56
63
|
|
57
64
|
file_name = join(dir, basename)
|
58
65
|
FileUtils.touch(file_name)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Hash
|
4
|
+
unless Hash.instance_methods(false).include?(:compact)
|
5
|
+
# Returns a hash with non +nil+ values.
|
6
|
+
#
|
7
|
+
# hash = { a: true, b: false, c: nil }
|
8
|
+
# hash.compact # => { a: true, b: false }
|
9
|
+
# hash # => { a: true, b: false, c: nil }
|
10
|
+
# { c: nil }.compact # => {}
|
11
|
+
# { c: true }.compact # => { c: true }
|
12
|
+
def compact
|
13
|
+
select { |_, value| !value.nil? }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
unless Hash.instance_methods(false).include?(:compact!)
|
18
|
+
# Replaces current hash with non +nil+ values.
|
19
|
+
# Returns +nil+ if no changes were made, otherwise returns the hash.
|
20
|
+
#
|
21
|
+
# hash = { a: true, b: false, c: nil }
|
22
|
+
# hash.compact! # => { a: true, b: false }
|
23
|
+
# hash # => { a: true, b: false }
|
24
|
+
# { c: true }.compact! # => nil
|
25
|
+
def compact!
|
26
|
+
reject! { |_, value| value.nil? }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|