activesupport 3.1.0 → 5.0.0
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 +7 -0
- data/CHANGELOG.md +798 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +13 -7
- data/lib/active_support/array_inquirer.rb +44 -0
- data/lib/active_support/backtrace_cleaner.rb +38 -34
- data/lib/active_support/benchmarkable.rb +17 -28
- data/lib/active_support/cache/file_store.rb +85 -70
- data/lib/active_support/cache/mem_cache_store.rb +75 -66
- data/lib/active_support/cache/memory_store.rb +31 -23
- data/lib/active_support/cache/null_store.rb +41 -0
- data/lib/active_support/cache/strategy/local_cache.rb +73 -70
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +44 -0
- data/lib/active_support/cache.rb +360 -294
- data/lib/active_support/callbacks.rb +563 -393
- data/lib/active_support/concern.rb +42 -34
- data/lib/active_support/concurrency/latch.rb +19 -0
- data/lib/active_support/concurrency/share_lock.rb +186 -0
- data/lib/active_support/configurable.rb +70 -12
- data/lib/active_support/core_ext/array/access.rb +53 -9
- data/lib/active_support/core_ext/array/conversions.rb +109 -62
- data/lib/active_support/core_ext/array/extract_options.rb +2 -2
- data/lib/active_support/core_ext/array/grouping.rb +39 -32
- data/lib/active_support/core_ext/array/inquiry.rb +17 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +7 -0
- data/lib/active_support/core_ext/array/wrap.rb +16 -18
- data/lib/active_support/core_ext/array.rb +2 -2
- data/lib/active_support/core_ext/benchmark.rb +7 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -36
- data/lib/active_support/core_ext/class/attribute.rb +47 -34
- data/lib/active_support/core_ext/class/attribute_accessors.rb +4 -79
- data/lib/active_support/core_ext/class/subclasses.rb +12 -7
- data/lib/active_support/core_ext/class.rb +0 -3
- data/lib/active_support/core_ext/date/blank.rb +12 -0
- data/lib/active_support/core_ext/date/calculations.rb +57 -167
- data/lib/active_support/core_ext/date/conversions.rb +31 -42
- data/lib/active_support/core_ext/date/zones.rb +2 -10
- data/lib/active_support/core_ext/date.rb +5 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +335 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +1 -0
- data/lib/active_support/core_ext/date_time/blank.rb +12 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +132 -65
- data/lib/active_support/core_ext/date_time/compatibility.rb +5 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +36 -34
- data/lib/active_support/core_ext/date_time.rb +5 -0
- data/lib/active_support/core_ext/digest/uuid.rb +51 -0
- data/lib/active_support/core_ext/enumerable.rb +81 -74
- data/lib/active_support/core_ext/file/atomic.rb +53 -26
- data/lib/active_support/core_ext/file.rb +0 -1
- data/lib/active_support/core_ext/hash/compact.rb +20 -0
- data/lib/active_support/core_ext/hash/conversions.rb +175 -70
- data/lib/active_support/core_ext/hash/deep_merge.rb +30 -8
- data/lib/active_support/core_ext/hash/except.rb +11 -12
- data/lib/active_support/core_ext/hash/indifferent_access.rb +7 -8
- data/lib/active_support/core_ext/hash/keys.rb +147 -24
- data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -3
- data/lib/active_support/core_ext/hash/slice.rb +22 -14
- data/lib/active_support/core_ext/hash/transform_values.rb +29 -0
- data/lib/active_support/core_ext/hash.rb +2 -2
- data/lib/active_support/core_ext/integer/inflections.rb +13 -1
- data/lib/active_support/core_ext/integer/multiple.rb +4 -0
- data/lib/active_support/core_ext/integer/time.rb +12 -22
- data/lib/active_support/core_ext/kernel/agnostics.rb +2 -2
- data/lib/active_support/core_ext/kernel/concern.rb +12 -0
- data/lib/active_support/core_ext/kernel/debugger.rb +2 -15
- data/lib/active_support/core_ext/kernel/reporting.rb +12 -62
- data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -7
- data/lib/active_support/core_ext/kernel.rb +2 -3
- data/lib/active_support/core_ext/load_error.rb +14 -7
- data/lib/active_support/core_ext/marshal.rb +22 -0
- data/lib/active_support/core_ext/module/aliasing.rb +16 -12
- data/lib/active_support/core_ext/module/anonymous.rb +12 -8
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
- data/lib/active_support/core_ext/module/attribute_accessors.rb +165 -13
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
- data/lib/active_support/core_ext/module/concerning.rb +135 -0
- data/lib/active_support/core_ext/module/delegation.rb +141 -68
- data/lib/active_support/core_ext/module/deprecation.rb +17 -3
- data/lib/active_support/core_ext/module/introspection.rb +9 -31
- data/lib/active_support/core_ext/module/method_transplanting.rb +3 -0
- data/lib/active_support/core_ext/module/qualified_const.rb +70 -0
- data/lib/active_support/core_ext/module/reachable.rb +1 -3
- data/lib/active_support/core_ext/module/remove_method.rb +24 -5
- data/lib/active_support/core_ext/module.rb +3 -3
- data/lib/active_support/core_ext/name_error.rb +15 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +20 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +145 -0
- data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
- data/lib/active_support/core_ext/numeric/time.rb +31 -36
- data/lib/active_support/core_ext/numeric.rb +2 -0
- data/lib/active_support/core_ext/object/acts_like.rb +4 -4
- data/lib/active_support/core_ext/object/blank.rb +52 -18
- data/lib/active_support/core_ext/object/deep_dup.rb +53 -0
- data/lib/active_support/core_ext/object/duplicable.rb +12 -20
- data/lib/active_support/core_ext/object/inclusion.rb +13 -1
- data/lib/active_support/core_ext/object/instance_variables.rb +7 -12
- data/lib/active_support/core_ext/object/json.rb +205 -0
- data/lib/active_support/core_ext/object/to_param.rb +1 -55
- data/lib/active_support/core_ext/object/to_query.rb +66 -9
- data/lib/active_support/core_ext/object/try.rb +124 -33
- data/lib/active_support/core_ext/object/with_options.rb +37 -11
- data/lib/active_support/core_ext/object.rb +2 -1
- data/lib/active_support/core_ext/range/conversions.rb +17 -7
- data/lib/active_support/core_ext/range/each.rb +21 -0
- data/lib/active_support/core_ext/range/include_range.rb +20 -18
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/range.rb +1 -2
- data/lib/active_support/core_ext/securerandom.rb +23 -0
- data/lib/active_support/core_ext/string/access.rb +95 -90
- data/lib/active_support/core_ext/string/behavior.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +41 -38
- data/lib/active_support/core_ext/string/exclude.rb +6 -1
- data/lib/active_support/core_ext/string/filters.rb +70 -17
- data/lib/active_support/core_ext/string/indent.rb +43 -0
- data/lib/active_support/core_ext/string/inflections.rb +139 -59
- data/lib/active_support/core_ext/string/inquiry.rb +2 -2
- data/lib/active_support/core_ext/string/multibyte.rb +46 -65
- data/lib/active_support/core_ext/string/output_safety.rb +153 -56
- data/lib/active_support/core_ext/string/strip.rb +3 -6
- data/lib/active_support/core_ext/string/zones.rb +14 -0
- data/lib/active_support/core_ext/string.rb +2 -3
- data/lib/active_support/core_ext/struct.rb +3 -0
- data/lib/active_support/core_ext/time/calculations.rb +173 -173
- data/lib/active_support/core_ext/time/compatibility.rb +5 -0
- data/lib/active_support/core_ext/time/conversions.rb +33 -29
- data/lib/active_support/core_ext/time/marshal.rb +2 -56
- data/lib/active_support/core_ext/time/zones.rb +57 -32
- data/lib/active_support/core_ext/time.rb +5 -0
- data/lib/active_support/core_ext/uri.rb +13 -19
- data/lib/active_support/core_ext.rb +3 -2
- data/lib/active_support/dependencies/autoload.rb +47 -20
- data/lib/active_support/dependencies/interlock.rb +51 -0
- data/lib/active_support/dependencies.rb +315 -265
- data/lib/active_support/deprecation/behaviors.rb +71 -30
- data/lib/active_support/deprecation/instance_delegator.rb +24 -0
- data/lib/active_support/deprecation/method_wrappers.rb +59 -18
- data/lib/active_support/deprecation/proxy_wrappers.rb +82 -14
- data/lib/active_support/deprecation/reporting.rb +61 -14
- data/lib/active_support/deprecation.rb +38 -13
- data/lib/active_support/descendants_tracker.rb +34 -19
- data/lib/active_support/duration/iso8601_parser.rb +122 -0
- data/lib/active_support/duration/iso8601_serializer.rb +51 -0
- data/lib/active_support/duration.rb +85 -14
- data/lib/active_support/evented_file_update_checker.rb +194 -0
- data/lib/active_support/execution_wrapper.rb +117 -0
- data/lib/active_support/executor.rb +6 -0
- data/lib/active_support/file_update_checker.rb +138 -17
- data/lib/active_support/gem_version.rb +15 -0
- data/lib/active_support/gzip.rb +11 -5
- data/lib/active_support/hash_with_indifferent_access.rb +199 -49
- data/lib/active_support/i18n.rb +6 -2
- data/lib/active_support/i18n_railtie.rb +40 -21
- data/lib/active_support/inflections.rb +22 -13
- data/lib/active_support/inflector/inflections.rb +175 -144
- data/lib/active_support/inflector/methods.rb +328 -91
- data/lib/active_support/inflector/transliterate.rb +51 -37
- data/lib/active_support/json/decoding.rb +31 -22
- data/lib/active_support/json/encoding.rb +88 -248
- data/lib/active_support/key_generator.rb +71 -0
- data/lib/active_support/lazy_load_hooks.rb +27 -25
- data/lib/active_support/locale/en.yml +102 -3
- data/lib/active_support/log_subscriber/test_helper.rb +24 -21
- data/lib/active_support/log_subscriber.rb +36 -49
- data/lib/active_support/logger.rb +106 -0
- data/lib/active_support/logger_silence.rb +28 -0
- data/lib/active_support/logger_thread_safe_level.rb +31 -0
- data/lib/active_support/message_encryptor.rb +72 -36
- data/lib/active_support/message_verifier.rb +96 -24
- data/lib/active_support/multibyte/chars.rb +88 -333
- data/lib/active_support/multibyte/unicode.rb +156 -136
- data/lib/active_support/multibyte.rb +5 -28
- data/lib/active_support/notifications/fanout.rb +115 -19
- data/lib/active_support/notifications/instrumenter.rb +52 -15
- data/lib/active_support/notifications.rb +168 -33
- data/lib/active_support/number_helper/number_converter.rb +182 -0
- data/lib/active_support/number_helper/number_to_currency_converter.rb +44 -0
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +28 -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 +62 -0
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +12 -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 +92 -0
- data/lib/active_support/number_helper.rb +368 -0
- data/lib/active_support/option_merger.rb +1 -1
- data/lib/active_support/ordered_hash.rb +18 -183
- data/lib/active_support/ordered_options.rb +44 -24
- data/lib/active_support/per_thread_registry.rb +58 -0
- data/lib/active_support/proxy_object.rb +13 -0
- data/lib/active_support/rails.rb +27 -0
- data/lib/active_support/railtie.rb +25 -34
- data/lib/active_support/reloader.rb +129 -0
- data/lib/active_support/rescuable.rb +98 -48
- data/lib/active_support/security_utils.rb +27 -0
- data/lib/active_support/string_inquirer.rb +14 -9
- data/lib/active_support/subscriber.rb +120 -0
- data/lib/active_support/tagged_logging.rb +78 -0
- data/lib/active_support/test_case.rb +69 -17
- data/lib/active_support/testing/assertions.rb +43 -41
- data/lib/active_support/testing/autorun.rb +12 -0
- data/lib/active_support/testing/constant_lookup.rb +50 -0
- data/lib/active_support/testing/declarative.rb +7 -21
- data/lib/active_support/testing/deprecation.rb +14 -33
- data/lib/active_support/testing/file_fixtures.rb +34 -0
- data/lib/active_support/testing/isolation.rb +53 -95
- data/lib/active_support/testing/method_call_assertions.rb +41 -0
- data/lib/active_support/testing/setup_and_teardown.rb +21 -82
- data/lib/active_support/testing/stream.rb +42 -0
- data/lib/active_support/testing/tagged_logging.rb +25 -0
- data/lib/active_support/testing/time_helpers.rb +134 -0
- data/lib/active_support/time.rb +6 -23
- data/lib/active_support/time_with_zone.rb +239 -92
- data/lib/active_support/values/time_zone.rb +236 -160
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +5 -7
- data/lib/active_support/xml_mini/jdom.rb +19 -13
- data/lib/active_support/xml_mini/libxml.rb +3 -4
- data/lib/active_support/xml_mini/libxmlsax.rb +2 -3
- data/lib/active_support/xml_mini/nokogiri.rb +3 -4
- data/lib/active_support/xml_mini/nokogirisax.rb +2 -3
- data/lib/active_support/xml_mini/rexml.rb +8 -10
- data/lib/active_support/xml_mini.rb +66 -34
- data/lib/active_support.rb +40 -23
- metadata +185 -134
- data/CHANGELOG +0 -1534
- data/lib/active_support/base64.rb +0 -42
- data/lib/active_support/basic_object.rb +0 -21
- data/lib/active_support/buffered_logger.rb +0 -137
- data/lib/active_support/cache/compressed_mem_cache_store.rb +0 -13
- data/lib/active_support/cache/synchronized_memory_store.rb +0 -11
- data/lib/active_support/core_ext/array/random_access.rb +0 -30
- data/lib/active_support/core_ext/array/uniq_by.rb +0 -16
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -44
- data/lib/active_support/core_ext/class/inheritable_attributes.rb +0 -178
- data/lib/active_support/core_ext/date/freeze.rb +0 -31
- data/lib/active_support/core_ext/date_time/zones.rb +0 -21
- data/lib/active_support/core_ext/exception.rb +0 -3
- data/lib/active_support/core_ext/file/path.rb +0 -5
- data/lib/active_support/core_ext/float/rounding.rb +0 -19
- data/lib/active_support/core_ext/float.rb +0 -1
- data/lib/active_support/core_ext/hash/deep_dup.rb +0 -11
- data/lib/active_support/core_ext/hash/diff.rb +0 -13
- data/lib/active_support/core_ext/kernel/requires.rb +0 -28
- data/lib/active_support/core_ext/logger.rb +0 -81
- data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +0 -31
- data/lib/active_support/core_ext/module/method_names.rb +0 -14
- data/lib/active_support/core_ext/module/synchronization.rb +0 -43
- data/lib/active_support/core_ext/object/to_json.rb +0 -19
- data/lib/active_support/core_ext/proc.rb +0 -14
- data/lib/active_support/core_ext/process/daemon.rb +0 -23
- data/lib/active_support/core_ext/process.rb +0 -1
- data/lib/active_support/core_ext/range/blockless_step.rb +0 -29
- data/lib/active_support/core_ext/range/cover.rb +0 -3
- data/lib/active_support/core_ext/rexml.rb +0 -46
- data/lib/active_support/core_ext/string/encoding.rb +0 -11
- data/lib/active_support/core_ext/string/interpolation.rb +0 -2
- data/lib/active_support/core_ext/string/xchar.rb +0 -18
- data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +0 -10
- data/lib/active_support/file_watcher.rb +0 -36
- data/lib/active_support/json/variable.rb +0 -9
- data/lib/active_support/memoizable.rb +0 -105
- data/lib/active_support/multibyte/exceptions.rb +0 -8
- data/lib/active_support/multibyte/utils.rb +0 -60
- data/lib/active_support/ruby/shim.rb +0 -22
- data/lib/active_support/secure_random.rb +0 -6
- data/lib/active_support/testing/mochaing.rb +0 -7
- data/lib/active_support/testing/pending.rb +0 -52
- data/lib/active_support/testing/performance/jruby.rb +0 -115
- data/lib/active_support/testing/performance/rubinius.rb +0 -113
- data/lib/active_support/testing/performance/ruby/mri.rb +0 -57
- data/lib/active_support/testing/performance/ruby/yarv.rb +0 -57
- data/lib/active_support/testing/performance/ruby.rb +0 -152
- data/lib/active_support/testing/performance.rb +0 -317
- data/lib/active_support/time/autoload.rb +0 -5
- data/lib/active_support/whiny_nil.rb +0 -60
@@ -1,13 +1,10 @@
|
|
1
|
+
require 'date'
|
1
2
|
require 'active_support/inflector/methods'
|
2
3
|
require 'active_support/core_ext/time/conversions'
|
3
4
|
require 'active_support/core_ext/date_time/calculations'
|
4
5
|
require 'active_support/values/time_zone'
|
5
6
|
|
6
7
|
class DateTime
|
7
|
-
# Ruby 1.9 has DateTime#to_time which internally relies on Time. We define our own #to_time which allows
|
8
|
-
# DateTimes outside the range of what can be created with Time.
|
9
|
-
remove_method :to_time if instance_methods.include?(:to_time)
|
10
|
-
|
11
8
|
# Convert to a formatted string. See Time::DATE_FORMATS for predefined formats.
|
12
9
|
#
|
13
10
|
# This method is aliased to <tt>to_s</tt>.
|
@@ -22,6 +19,7 @@ class DateTime
|
|
22
19
|
# datetime.to_formatted_s(:long) # => "December 04, 2007 00:00"
|
23
20
|
# datetime.to_formatted_s(:long_ordinal) # => "December 4th, 2007 00:00"
|
24
21
|
# datetime.to_formatted_s(:rfc822) # => "Tue, 04 Dec 2007 00:00:00 +0000"
|
22
|
+
# datetime.to_formatted_s(:iso8601) # => "2007-12-04T00:00:00+00:00"
|
25
23
|
#
|
26
24
|
# == Adding your own datetime formats to to_formatted_s
|
27
25
|
# DateTime formats are shared with Time. You can add your own to the
|
@@ -30,7 +28,7 @@ class DateTime
|
|
30
28
|
# datetime argument as the value.
|
31
29
|
#
|
32
30
|
# # config/initializers/time_formats.rb
|
33
|
-
# Time::DATE_FORMATS[:month_and_year] =
|
31
|
+
# Time::DATE_FORMATS[:month_and_year] = '%B %Y'
|
34
32
|
# Time::DATE_FORMATS[:short_ordinal] = lambda { |time| time.strftime("%B #{time.day.ordinalize}") }
|
35
33
|
def to_formatted_s(format = :default)
|
36
34
|
if formatter = ::Time::DATE_FORMATS[format]
|
@@ -39,10 +37,11 @@ class DateTime
|
|
39
37
|
to_default_s
|
40
38
|
end
|
41
39
|
end
|
42
|
-
alias_method :to_default_s, :to_s
|
40
|
+
alias_method :to_default_s, :to_s if instance_methods(false).include?(:to_s)
|
43
41
|
alias_method :to_s, :to_formatted_s
|
44
42
|
|
45
|
-
# Returns the
|
43
|
+
# Returns a formatted string of the offset from UTC, or an alternative
|
44
|
+
# string if the time zone is already UTC.
|
46
45
|
#
|
47
46
|
# datetime = DateTime.civil(2000, 1, 1, 0, 0, 0, Rational(-6, 24))
|
48
47
|
# datetime.formatted_offset # => "-06:00"
|
@@ -58,46 +57,49 @@ class DateTime
|
|
58
57
|
alias_method :default_inspect, :inspect
|
59
58
|
alias_method :inspect, :readable_inspect
|
60
59
|
|
61
|
-
#
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
#
|
67
|
-
#
|
68
|
-
def to_time
|
69
|
-
self.offset == 0 ? ::Time.utc_time(year, month, day, hour, min, sec, sec_fraction * (RUBY_VERSION < '1.9' ? 86400000000 : 1000000)) : self
|
70
|
-
end
|
71
|
-
|
72
|
-
# To be able to keep Times, Dates and DateTimes interchangeable on conversions.
|
73
|
-
def to_datetime
|
74
|
-
self
|
75
|
-
end unless instance_methods(false).include?(:to_datetime)
|
76
|
-
|
60
|
+
# Returns DateTime with local offset for given year if format is local else
|
61
|
+
# offset is zero.
|
62
|
+
#
|
63
|
+
# DateTime.civil_from_format :local, 2012
|
64
|
+
# # => Sun, 01 Jan 2012 00:00:00 +0300
|
65
|
+
# DateTime.civil_from_format :local, 2012, 12, 17
|
66
|
+
# # => Mon, 17 Dec 2012 00:00:00 +0000
|
77
67
|
def self.civil_from_format(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0)
|
78
|
-
|
68
|
+
if utc_or_local.to_sym == :local
|
69
|
+
offset = ::Time.local(year, month, day).utc_offset.to_r / 86400
|
70
|
+
else
|
71
|
+
offset = 0
|
72
|
+
end
|
79
73
|
civil(year, month, day, hour, min, sec, offset)
|
80
74
|
end
|
81
75
|
|
82
|
-
# Converts
|
83
|
-
def xmlschema
|
84
|
-
strftime("%Y-%m-%dT%H:%M:%S%Z")
|
85
|
-
end unless instance_methods(false).include?(:xmlschema)
|
86
|
-
|
87
|
-
# Converts self to a floating-point number of seconds since the Unix epoch.
|
76
|
+
# Converts +self+ to a floating-point number of seconds, including fractional microseconds, since the Unix epoch.
|
88
77
|
def to_f
|
89
|
-
seconds_since_unix_epoch.to_f
|
78
|
+
seconds_since_unix_epoch.to_f + sec_fraction
|
90
79
|
end
|
91
80
|
|
92
|
-
# Converts self to an integer number of seconds since the Unix epoch.
|
81
|
+
# Converts +self+ to an integer number of seconds since the Unix epoch.
|
93
82
|
def to_i
|
94
83
|
seconds_since_unix_epoch.to_i
|
95
84
|
end
|
96
85
|
|
86
|
+
# Returns the fraction of a second as microseconds
|
87
|
+
def usec
|
88
|
+
(sec_fraction * 1_000_000).to_i
|
89
|
+
end
|
90
|
+
|
91
|
+
# Returns the fraction of a second as nanoseconds
|
92
|
+
def nsec
|
93
|
+
(sec_fraction * 1_000_000_000).to_i
|
94
|
+
end
|
95
|
+
|
97
96
|
private
|
98
97
|
|
98
|
+
def offset_in_seconds
|
99
|
+
(offset * 86400).to_i
|
100
|
+
end
|
101
|
+
|
99
102
|
def seconds_since_unix_epoch
|
100
|
-
|
101
|
-
(self - ::DateTime.civil(1970)) * seconds_per_day
|
103
|
+
(jd - 2440588) * 86400 - offset_in_seconds + seconds_since_midnight
|
102
104
|
end
|
103
105
|
end
|
@@ -0,0 +1,5 @@
|
|
1
|
+
require 'active_support/core_ext/date_time/acts_like'
|
2
|
+
require 'active_support/core_ext/date_time/blank'
|
3
|
+
require 'active_support/core_ext/date_time/calculations'
|
4
|
+
require 'active_support/core_ext/date_time/compatibility'
|
5
|
+
require 'active_support/core_ext/date_time/conversions'
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
module Digest
|
4
|
+
module UUID
|
5
|
+
DNS_NAMESPACE = "k\xA7\xB8\x10\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
|
6
|
+
URL_NAMESPACE = "k\xA7\xB8\x11\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
|
7
|
+
OID_NAMESPACE = "k\xA7\xB8\x12\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
|
8
|
+
X500_NAMESPACE = "k\xA7\xB8\x14\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
|
9
|
+
|
10
|
+
# Generates a v5 non-random UUID (Universally Unique IDentifier).
|
11
|
+
#
|
12
|
+
# Using Digest::MD5 generates version 3 UUIDs; Digest::SHA1 generates version 5 UUIDs.
|
13
|
+
# uuid_from_hash always generates the same UUID for a given name and namespace combination.
|
14
|
+
#
|
15
|
+
# See RFC 4122 for details of UUID at: http://www.ietf.org/rfc/rfc4122.txt
|
16
|
+
def self.uuid_from_hash(hash_class, uuid_namespace, name)
|
17
|
+
if hash_class == Digest::MD5
|
18
|
+
version = 3
|
19
|
+
elsif hash_class == Digest::SHA1
|
20
|
+
version = 5
|
21
|
+
else
|
22
|
+
raise ArgumentError, "Expected Digest::SHA1 or Digest::MD5, got #{hash_class.name}."
|
23
|
+
end
|
24
|
+
|
25
|
+
hash = hash_class.new
|
26
|
+
hash.update(uuid_namespace)
|
27
|
+
hash.update(name)
|
28
|
+
|
29
|
+
ary = hash.digest.unpack('NnnnnN')
|
30
|
+
ary[2] = (ary[2] & 0x0FFF) | (version << 12)
|
31
|
+
ary[3] = (ary[3] & 0x3FFF) | 0x8000
|
32
|
+
|
33
|
+
"%08x-%04x-%04x-%04x-%04x%08x" % ary
|
34
|
+
end
|
35
|
+
|
36
|
+
# Convenience method for uuid_from_hash using Digest::MD5.
|
37
|
+
def self.uuid_v3(uuid_namespace, name)
|
38
|
+
self.uuid_from_hash(Digest::MD5, uuid_namespace, name)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Convenience method for uuid_from_hash using Digest::SHA1.
|
42
|
+
def self.uuid_v5(uuid_namespace, name)
|
43
|
+
self.uuid_from_hash(Digest::SHA1, uuid_namespace, name)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Convenience method for SecureRandom.uuid.
|
47
|
+
def self.uuid_v4
|
48
|
+
SecureRandom.uuid
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -1,41 +1,5 @@
|
|
1
|
-
require 'active_support/ordered_hash'
|
2
|
-
|
3
1
|
module Enumerable
|
4
|
-
#
|
5
|
-
remove_method(:group_by) if [].respond_to?(:group_by) && RUBY_VERSION < '1.9'
|
6
|
-
|
7
|
-
# Collect an enumerable into sets, grouped by the result of a block. Useful,
|
8
|
-
# for example, for grouping records by date.
|
9
|
-
#
|
10
|
-
# Example:
|
11
|
-
#
|
12
|
-
# latest_transcripts.group_by(&:day).each do |day, transcripts|
|
13
|
-
# p "#{day} -> #{transcripts.map(&:class).join(', ')}"
|
14
|
-
# end
|
15
|
-
# "2006-03-01 -> Transcript"
|
16
|
-
# "2006-02-28 -> Transcript"
|
17
|
-
# "2006-02-27 -> Transcript, Transcript"
|
18
|
-
# "2006-02-26 -> Transcript, Transcript"
|
19
|
-
# "2006-02-25 -> Transcript"
|
20
|
-
# "2006-02-24 -> Transcript, Transcript"
|
21
|
-
# "2006-02-23 -> Transcript"
|
22
|
-
def group_by
|
23
|
-
assoc = ActiveSupport::OrderedHash.new
|
24
|
-
|
25
|
-
each do |element|
|
26
|
-
key = yield(element)
|
27
|
-
|
28
|
-
if assoc.has_key?(key)
|
29
|
-
assoc[key] << element
|
30
|
-
else
|
31
|
-
assoc[key] = [element]
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
assoc
|
36
|
-
end unless [].respond_to?(:group_by)
|
37
|
-
|
38
|
-
# Calculates a sum from the elements. Examples:
|
2
|
+
# Calculates a sum from the elements.
|
39
3
|
#
|
40
4
|
# payments.sum { |p| p.price * p.tax_rate }
|
41
5
|
# payments.sum(&:price)
|
@@ -47,71 +11,114 @@ module Enumerable
|
|
47
11
|
# It can also calculate the sum without the use of a block.
|
48
12
|
#
|
49
13
|
# [5, 15, 10].sum # => 30
|
50
|
-
# [
|
14
|
+
# ['foo', 'bar'].sum # => "foobar"
|
51
15
|
# [[1, 2], [3, 1, 5]].sum => [1, 2, 3, 1, 5]
|
52
16
|
#
|
53
17
|
# The default sum of an empty list is zero. You can override this default:
|
54
18
|
#
|
55
19
|
# [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
|
56
|
-
|
57
|
-
def sum(identity = 0, &block)
|
20
|
+
def sum(identity = nil, &block)
|
58
21
|
if block_given?
|
59
22
|
map(&block).sum(identity)
|
60
23
|
else
|
61
|
-
|
24
|
+
sum = identity ? inject(identity, :+) : inject(:+)
|
25
|
+
sum || identity || 0
|
62
26
|
end
|
63
27
|
end
|
64
28
|
|
65
|
-
#
|
66
|
-
# +memo+ to the block. Handy for building up hashes or
|
67
|
-
# reducing collections down to one object. Examples:
|
68
|
-
#
|
69
|
-
# %w(foo bar).each_with_object({}) { |str, hsh| hsh[str] = str.upcase }
|
70
|
-
# # => {'foo' => 'FOO', 'bar' => 'BAR'}
|
71
|
-
#
|
72
|
-
# *Note* that you can't use immutable objects like numbers, true or false as
|
73
|
-
# the memo. You would think the following returns 120, but since the memo is
|
74
|
-
# never changed, it does not.
|
75
|
-
#
|
76
|
-
# (1..5).each_with_object(1) { |value, memo| memo *= value } # => 1
|
77
|
-
#
|
78
|
-
def each_with_object(memo, &block)
|
79
|
-
each do |element|
|
80
|
-
block.call(element, memo)
|
81
|
-
end
|
82
|
-
memo
|
83
|
-
end unless [].respond_to?(:each_with_object)
|
84
|
-
|
85
|
-
# Convert an enumerable to a hash. Examples:
|
29
|
+
# Convert an enumerable to a hash.
|
86
30
|
#
|
87
31
|
# people.index_by(&:login)
|
88
32
|
# => { "nextangle" => <Person ...>, "chade-" => <Person ...>, ...}
|
89
33
|
# people.index_by { |person| "#{person.first_name} #{person.last_name}" }
|
90
34
|
# => { "Chade- Fowlersburg-e" => <Person ...>, "David Heinemeier Hansson" => <Person ...>, ...}
|
91
|
-
#
|
92
35
|
def index_by
|
93
|
-
|
36
|
+
if block_given?
|
37
|
+
Hash[map { |elem| [yield(elem), elem] }]
|
38
|
+
else
|
39
|
+
to_enum(:index_by) { size if respond_to?(:size) }
|
40
|
+
end
|
94
41
|
end
|
95
42
|
|
96
|
-
# Returns true if the
|
97
|
-
# Can be called with a block too,
|
98
|
-
|
99
|
-
|
100
|
-
|
43
|
+
# Returns +true+ if the enumerable has more than 1 element. Functionally
|
44
|
+
# equivalent to <tt>enum.to_a.size > 1</tt>. Can be called with a block too,
|
45
|
+
# much like any?, so <tt>people.many? { |p| p.age > 26 }</tt> returns +true+
|
46
|
+
# if more than one person is over 26.
|
47
|
+
def many?
|
48
|
+
cnt = 0
|
49
|
+
if block_given?
|
50
|
+
any? do |element|
|
51
|
+
cnt += 1 if yield element
|
52
|
+
cnt > 1
|
53
|
+
end
|
54
|
+
else
|
55
|
+
any? { (cnt += 1) > 1 }
|
56
|
+
end
|
101
57
|
end
|
102
58
|
|
103
|
-
# The negative of the Enumerable#include
|
59
|
+
# The negative of the <tt>Enumerable#include?</tt>. Returns +true+ if the
|
60
|
+
# collection does not include the object.
|
104
61
|
def exclude?(object)
|
105
62
|
!include?(object)
|
106
63
|
end
|
64
|
+
|
65
|
+
# Returns a copy of the enumerable without the specified elements.
|
66
|
+
#
|
67
|
+
# ["David", "Rafael", "Aaron", "Todd"].without "Aaron", "Todd"
|
68
|
+
# => ["David", "Rafael"]
|
69
|
+
#
|
70
|
+
# {foo: 1, bar: 2, baz: 3}.without :bar
|
71
|
+
# => {foo: 1, baz: 3}
|
72
|
+
def without(*elements)
|
73
|
+
reject { |element| elements.include?(element) }
|
74
|
+
end
|
75
|
+
|
76
|
+
# Convert an enumerable to an array based on the given key.
|
77
|
+
#
|
78
|
+
# [{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pluck(:name)
|
79
|
+
# => ["David", "Rafael", "Aaron"]
|
80
|
+
#
|
81
|
+
# [{ id: 1, name: "David" }, { id: 2, name: "Rafael" }].pluck(:id, :name)
|
82
|
+
# => [[1, "David"], [2, "Rafael"]]
|
83
|
+
def pluck(*keys)
|
84
|
+
if keys.many?
|
85
|
+
map { |element| keys.map { |key| element[key] } }
|
86
|
+
else
|
87
|
+
map { |element| element[keys.first] }
|
88
|
+
end
|
89
|
+
end
|
107
90
|
end
|
108
91
|
|
109
92
|
class Range #:nodoc:
|
110
93
|
# Optimize range sum to use arithmetic progression if a block is not given and
|
111
94
|
# we have a range of numeric values.
|
112
|
-
def sum(identity =
|
113
|
-
|
114
|
-
|
115
|
-
|
95
|
+
def sum(identity = nil)
|
96
|
+
if block_given? || !(first.is_a?(Integer) && last.is_a?(Integer))
|
97
|
+
super
|
98
|
+
else
|
99
|
+
actual_last = exclude_end? ? (last - 1) : last
|
100
|
+
if actual_last >= first
|
101
|
+
sum = identity || 0
|
102
|
+
sum + (actual_last - first + 1) * (actual_last + first) / 2
|
103
|
+
else
|
104
|
+
identity || 0
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Array#sum was added in Ruby 2.4 but it only works with Numeric elements.
|
111
|
+
#
|
112
|
+
# We tried shimming it to attempt the fast native method, rescue TypeError,
|
113
|
+
# and fall back to the compatible implementation, but that's much slower than
|
114
|
+
# just calling the compat method in the first place.
|
115
|
+
if Array.instance_methods(false).include?(:sum) && !(%w[a].sum rescue false)
|
116
|
+
class Array
|
117
|
+
remove_method :sum
|
118
|
+
|
119
|
+
def sum(*args) #:nodoc:
|
120
|
+
# Use Enumerable#sum instead.
|
121
|
+
super
|
122
|
+
end
|
116
123
|
end
|
117
124
|
end
|
@@ -1,41 +1,68 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
1
3
|
class File
|
2
|
-
# Write to a file atomically.
|
4
|
+
# Write to a file atomically. Useful for situations where you don't
|
3
5
|
# want other processes or threads to see half-written files.
|
4
6
|
#
|
5
|
-
# File.atomic_write(
|
6
|
-
# file.write(
|
7
|
+
# File.atomic_write('important.file') do |file|
|
8
|
+
# file.write('hello')
|
7
9
|
# end
|
8
10
|
#
|
9
|
-
#
|
10
|
-
#
|
11
|
+
# This method needs to create a temporary file. By default it will create it
|
12
|
+
# in the same directory as the destination file. If you don't like this
|
13
|
+
# behavior you can provide a different directory but it must be on the
|
14
|
+
# same physical filesystem as the file you're trying to write.
|
11
15
|
#
|
12
|
-
# File.atomic_write(
|
13
|
-
# file.write(
|
16
|
+
# File.atomic_write('/data/something.important', '/data/tmp') do |file|
|
17
|
+
# file.write('hello')
|
14
18
|
# end
|
15
|
-
def self.atomic_write(file_name, temp_dir =
|
19
|
+
def self.atomic_write(file_name, temp_dir = dirname(file_name))
|
16
20
|
require 'tempfile' unless defined?(Tempfile)
|
17
|
-
require 'fileutils' unless defined?(FileUtils)
|
18
21
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
+
Tempfile.open(".#{basename(file_name)}", temp_dir) do |temp_file|
|
23
|
+
temp_file.binmode
|
24
|
+
return_val = yield temp_file
|
25
|
+
temp_file.close
|
26
|
+
|
27
|
+
old_stat = if exist?(file_name)
|
28
|
+
# Get original file permissions
|
29
|
+
stat(file_name)
|
30
|
+
elsif temp_dir != dirname(file_name)
|
31
|
+
# If not possible, probe which are the default permissions in the
|
32
|
+
# destination directory.
|
33
|
+
probe_stat_in(dirname(file_name))
|
34
|
+
end
|
22
35
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
36
|
+
if old_stat
|
37
|
+
# Set correct permissions on new file
|
38
|
+
begin
|
39
|
+
chown(old_stat.uid, old_stat.gid, temp_file.path)
|
40
|
+
# This operation will affect filesystem ACL's
|
41
|
+
chmod(old_stat.mode, temp_file.path)
|
42
|
+
rescue Errno::EPERM, Errno::EACCES
|
43
|
+
# Changing file ownership failed, moving on.
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Overwrite original file with temp file
|
48
|
+
rename(temp_file.path, file_name)
|
49
|
+
return_val
|
32
50
|
end
|
51
|
+
end
|
33
52
|
|
34
|
-
|
35
|
-
|
53
|
+
# Private utility method.
|
54
|
+
def self.probe_stat_in(dir) #:nodoc:
|
55
|
+
basename = [
|
56
|
+
'.permissions_check',
|
57
|
+
Thread.current.object_id,
|
58
|
+
Process.pid,
|
59
|
+
rand(1000000)
|
60
|
+
].join('.')
|
36
61
|
|
37
|
-
|
38
|
-
|
39
|
-
|
62
|
+
file_name = join(dir, basename)
|
63
|
+
FileUtils.touch(file_name)
|
64
|
+
stat(file_name)
|
65
|
+
ensure
|
66
|
+
FileUtils.rm_f(file_name) if file_name
|
40
67
|
end
|
41
68
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Hash
|
2
|
+
# Returns a hash with non +nil+ values.
|
3
|
+
#
|
4
|
+
# hash = { a: true, b: false, c: nil}
|
5
|
+
# hash.compact # => { a: true, b: false}
|
6
|
+
# hash # => { a: true, b: false, c: nil}
|
7
|
+
# { c: nil }.compact # => {}
|
8
|
+
def compact
|
9
|
+
self.select { |_, value| !value.nil? }
|
10
|
+
end
|
11
|
+
|
12
|
+
# Replaces current hash with non +nil+ values.
|
13
|
+
#
|
14
|
+
# hash = { a: true, b: false, c: nil}
|
15
|
+
# hash.compact! # => { a: true, b: false}
|
16
|
+
# hash # => { a: true, b: false}
|
17
|
+
def compact!
|
18
|
+
self.reject! { |_, value| value.nil? }
|
19
|
+
end
|
20
|
+
end
|