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
@@ -1,4 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/object/to_param"
|
4
|
+
require "active_support/core_ext/object/to_query"
|
5
|
+
require "active_support/core_ext/array/conversions"
|
6
|
+
require "active_support/core_ext/hash/conversions"
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/object/duplicable"
|
2
4
|
|
3
5
|
class Object
|
4
6
|
# Returns a deep copy of object if it's duplicable. If it's
|
@@ -8,8 +10,8 @@ class Object
|
|
8
10
|
# dup = object.deep_dup
|
9
11
|
# dup.instance_variable_set(:@a, 1)
|
10
12
|
#
|
11
|
-
# object.instance_variable_defined?(:@a)
|
12
|
-
# dup.instance_variable_defined?(:@a)
|
13
|
+
# object.instance_variable_defined?(:@a) # => false
|
14
|
+
# dup.instance_variable_defined?(:@a) # => true
|
13
15
|
def deep_dup
|
14
16
|
duplicable? ? dup : self
|
15
17
|
end
|
@@ -22,10 +24,10 @@ class Array
|
|
22
24
|
# dup = array.deep_dup
|
23
25
|
# dup[1][2] = 4
|
24
26
|
#
|
25
|
-
# array[1][2]
|
26
|
-
# dup[1][2]
|
27
|
+
# array[1][2] # => nil
|
28
|
+
# dup[1][2] # => 4
|
27
29
|
def deep_dup
|
28
|
-
map
|
30
|
+
map(&:deep_dup)
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
@@ -36,11 +38,18 @@ class Hash
|
|
36
38
|
# dup = hash.deep_dup
|
37
39
|
# dup[:a][:c] = 'c'
|
38
40
|
#
|
39
|
-
# hash[:a][:c]
|
40
|
-
# dup[:a][:c]
|
41
|
+
# hash[:a][:c] # => nil
|
42
|
+
# dup[:a][:c] # => "c"
|
41
43
|
def deep_dup
|
42
|
-
|
43
|
-
|
44
|
+
hash = dup
|
45
|
+
each_pair do |key, value|
|
46
|
+
if key.frozen? && ::String === key
|
47
|
+
hash[key] = value.deep_dup
|
48
|
+
else
|
49
|
+
hash.delete(key)
|
50
|
+
hash[key.deep_dup] = value.deep_dup
|
51
|
+
end
|
44
52
|
end
|
53
|
+
hash
|
45
54
|
end
|
46
55
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#--
|
2
|
-
# Most objects are cloneable, but not all. For example you can't dup
|
4
|
+
# Most objects are cloneable, but not all. For example you can't dup methods:
|
3
5
|
#
|
4
|
-
#
|
6
|
+
# method(:puts).dup # => TypeError: allocator undefined for Method
|
5
7
|
#
|
6
8
|
# Classes may signal their instances are not duplicable removing +dup+/+clone+
|
7
9
|
# or raising exceptions from them. So, to dup an arbitrary object you normally
|
@@ -19,7 +21,7 @@
|
|
19
21
|
class Object
|
20
22
|
# Can you safely dup this object?
|
21
23
|
#
|
22
|
-
# False for
|
24
|
+
# False for method objects;
|
23
25
|
# true otherwise.
|
24
26
|
def duplicable?
|
25
27
|
true
|
@@ -27,64 +29,128 @@ class Object
|
|
27
29
|
end
|
28
30
|
|
29
31
|
class NilClass
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
begin
|
33
|
+
nil.dup
|
34
|
+
rescue TypeError
|
35
|
+
|
36
|
+
# +nil+ is not duplicable:
|
37
|
+
#
|
38
|
+
# nil.duplicable? # => false
|
39
|
+
# nil.dup # => TypeError: can't dup NilClass
|
40
|
+
def duplicable?
|
41
|
+
false
|
42
|
+
end
|
36
43
|
end
|
37
44
|
end
|
38
45
|
|
39
46
|
class FalseClass
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
47
|
+
begin
|
48
|
+
false.dup
|
49
|
+
rescue TypeError
|
50
|
+
|
51
|
+
# +false+ is not duplicable:
|
52
|
+
#
|
53
|
+
# false.duplicable? # => false
|
54
|
+
# false.dup # => TypeError: can't dup FalseClass
|
55
|
+
def duplicable?
|
56
|
+
false
|
57
|
+
end
|
46
58
|
end
|
47
59
|
end
|
48
60
|
|
49
61
|
class TrueClass
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
62
|
+
begin
|
63
|
+
true.dup
|
64
|
+
rescue TypeError
|
65
|
+
|
66
|
+
# +true+ is not duplicable:
|
67
|
+
#
|
68
|
+
# true.duplicable? # => false
|
69
|
+
# true.dup # => TypeError: can't dup TrueClass
|
70
|
+
def duplicable?
|
71
|
+
false
|
72
|
+
end
|
56
73
|
end
|
57
74
|
end
|
58
75
|
|
59
76
|
class Symbol
|
60
|
-
|
77
|
+
begin
|
78
|
+
:symbol.dup # Ruby 2.4.x.
|
79
|
+
"symbol_from_string".to_sym.dup # Some symbols can't `dup` in Ruby 2.4.0.
|
80
|
+
rescue TypeError
|
81
|
+
|
82
|
+
# Symbols are not duplicable:
|
83
|
+
#
|
84
|
+
# :my_symbol.duplicable? # => false
|
85
|
+
# :my_symbol.dup # => TypeError: can't dup Symbol
|
86
|
+
def duplicable?
|
87
|
+
false
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class Numeric
|
93
|
+
begin
|
94
|
+
1.dup
|
95
|
+
rescue TypeError
|
96
|
+
|
97
|
+
# Numbers are not duplicable:
|
98
|
+
#
|
99
|
+
# 3.duplicable? # => false
|
100
|
+
# 3.dup # => TypeError: can't dup Integer
|
101
|
+
def duplicable?
|
102
|
+
false
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
require "bigdecimal"
|
108
|
+
class BigDecimal
|
109
|
+
# BigDecimals are duplicable:
|
61
110
|
#
|
62
|
-
#
|
63
|
-
#
|
111
|
+
# BigDecimal("1.2").duplicable? # => true
|
112
|
+
# BigDecimal("1.2").dup # => #<BigDecimal:...,'0.12E1',18(18)>
|
64
113
|
def duplicable?
|
65
|
-
|
114
|
+
true
|
66
115
|
end
|
67
116
|
end
|
68
117
|
|
69
|
-
class
|
70
|
-
#
|
118
|
+
class Method
|
119
|
+
# Methods are not duplicable:
|
71
120
|
#
|
72
|
-
#
|
73
|
-
#
|
121
|
+
# method(:puts).duplicable? # => false
|
122
|
+
# method(:puts).dup # => TypeError: allocator undefined for Method
|
74
123
|
def duplicable?
|
75
124
|
false
|
76
125
|
end
|
77
126
|
end
|
78
127
|
|
79
|
-
|
80
|
-
class BigDecimal
|
128
|
+
class Complex
|
81
129
|
begin
|
82
|
-
|
130
|
+
Complex(1).dup
|
131
|
+
rescue TypeError
|
83
132
|
|
133
|
+
# Complexes are not duplicable:
|
134
|
+
#
|
135
|
+
# Complex(1).duplicable? # => false
|
136
|
+
# Complex(1).dup # => TypeError: can't copy Complex
|
84
137
|
def duplicable?
|
85
|
-
|
138
|
+
false
|
86
139
|
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
class Rational
|
144
|
+
begin
|
145
|
+
Rational(1).dup
|
87
146
|
rescue TypeError
|
88
|
-
|
147
|
+
|
148
|
+
# Rationals are not duplicable:
|
149
|
+
#
|
150
|
+
# Rational(1).duplicable? # => false
|
151
|
+
# Rational(1).dup # => TypeError: can't copy Rational
|
152
|
+
def duplicable?
|
153
|
+
false
|
154
|
+
end
|
89
155
|
end
|
90
156
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Object
|
4
4
|
# Returns true if this object is included in the argument. Argument must be
|
@@ -7,20 +7,23 @@ class Object
|
|
7
7
|
# characters = ["Konata", "Kagami", "Tsukasa"]
|
8
8
|
# "Konata".in?(characters) # => true
|
9
9
|
#
|
10
|
-
# This will throw an ArgumentError if the argument doesn't respond
|
10
|
+
# This will throw an +ArgumentError+ if the argument doesn't respond
|
11
11
|
# to +#include?+.
|
12
|
-
def in?(
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
12
|
+
def in?(another_object)
|
13
|
+
another_object.include?(self)
|
14
|
+
rescue NoMethodError
|
15
|
+
raise ArgumentError.new("The parameter passed to #in? must respond to #include?")
|
16
|
+
end
|
17
|
+
|
18
|
+
# Returns the receiver if it's included in the argument otherwise returns +nil+.
|
19
|
+
# Argument must be any object which responds to +#include?+. Usage:
|
20
|
+
#
|
21
|
+
# params[:bucket_type].presence_in %w( project calendar )
|
22
|
+
#
|
23
|
+
# This will throw an +ArgumentError+ if the argument doesn't respond to +#include?+.
|
24
|
+
#
|
25
|
+
# @return [Object]
|
26
|
+
def presence_in(another_object)
|
27
|
+
in?(another_object) ? self : nil
|
25
28
|
end
|
26
29
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Object
|
2
4
|
# Returns a hash with string keys that maps instance variable names without "@" to their
|
3
5
|
# corresponding values.
|
@@ -23,6 +25,6 @@ class Object
|
|
23
25
|
#
|
24
26
|
# C.new(0, 1).instance_variable_names # => ["@y", "@x"]
|
25
27
|
def instance_variable_names
|
26
|
-
instance_variables.map
|
28
|
+
instance_variables.map(&:to_s)
|
27
29
|
end
|
28
30
|
end
|
@@ -0,0 +1,227 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Hack to load json gem first so we can overwrite its to_json.
|
4
|
+
require "json"
|
5
|
+
require "bigdecimal"
|
6
|
+
require "uri/generic"
|
7
|
+
require "pathname"
|
8
|
+
require "active_support/core_ext/big_decimal/conversions" # for #to_s
|
9
|
+
require "active_support/core_ext/hash/except"
|
10
|
+
require "active_support/core_ext/hash/slice"
|
11
|
+
require "active_support/core_ext/object/instance_variables"
|
12
|
+
require "time"
|
13
|
+
require "active_support/core_ext/time/conversions"
|
14
|
+
require "active_support/core_ext/date_time/conversions"
|
15
|
+
require "active_support/core_ext/date/conversions"
|
16
|
+
|
17
|
+
# The JSON gem adds a few modules to Ruby core classes containing :to_json definition, overwriting
|
18
|
+
# their default behavior. That said, we need to define the basic to_json method in all of them,
|
19
|
+
# otherwise they will always use to_json gem implementation, which is backwards incompatible in
|
20
|
+
# several cases (for instance, the JSON implementation for Hash does not work) with inheritance
|
21
|
+
# and consequently classes as ActiveSupport::OrderedHash cannot be serialized to json.
|
22
|
+
#
|
23
|
+
# On the other hand, we should avoid conflict with ::JSON.{generate,dump}(obj). Unfortunately, the
|
24
|
+
# JSON gem's encoder relies on its own to_json implementation to encode objects. Since it always
|
25
|
+
# passes a ::JSON::State object as the only argument to to_json, we can detect that and forward the
|
26
|
+
# calls to the original to_json method.
|
27
|
+
#
|
28
|
+
# It should be noted that when using ::JSON.{generate,dump} directly, ActiveSupport's encoder is
|
29
|
+
# bypassed completely. This means that as_json won't be invoked and the JSON gem will simply
|
30
|
+
# ignore any options it does not natively understand. This also means that ::JSON.{generate,dump}
|
31
|
+
# should give exactly the same results with or without active support.
|
32
|
+
|
33
|
+
module ActiveSupport
|
34
|
+
module ToJsonWithActiveSupportEncoder # :nodoc:
|
35
|
+
def to_json(options = nil)
|
36
|
+
if options.is_a?(::JSON::State)
|
37
|
+
# Called from JSON.{generate,dump}, forward it to JSON gem's to_json
|
38
|
+
super(options)
|
39
|
+
else
|
40
|
+
# to_json is being invoked directly, use ActiveSupport's encoder
|
41
|
+
ActiveSupport::JSON.encode(self, options)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
[Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass, Enumerable].reverse_each do |klass|
|
48
|
+
klass.prepend(ActiveSupport::ToJsonWithActiveSupportEncoder)
|
49
|
+
end
|
50
|
+
|
51
|
+
class Object
|
52
|
+
def as_json(options = nil) #:nodoc:
|
53
|
+
if respond_to?(:to_hash)
|
54
|
+
to_hash.as_json(options)
|
55
|
+
else
|
56
|
+
instance_values.as_json(options)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class Struct #:nodoc:
|
62
|
+
def as_json(options = nil)
|
63
|
+
Hash[members.zip(values)].as_json(options)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class TrueClass
|
68
|
+
def as_json(options = nil) #:nodoc:
|
69
|
+
self
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class FalseClass
|
74
|
+
def as_json(options = nil) #:nodoc:
|
75
|
+
self
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
class NilClass
|
80
|
+
def as_json(options = nil) #:nodoc:
|
81
|
+
self
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
class String
|
86
|
+
def as_json(options = nil) #:nodoc:
|
87
|
+
self
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class Symbol
|
92
|
+
def as_json(options = nil) #:nodoc:
|
93
|
+
to_s
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
class Numeric
|
98
|
+
def as_json(options = nil) #:nodoc:
|
99
|
+
self
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
class Float
|
104
|
+
# Encoding Infinity or NaN to JSON should return "null". The default returns
|
105
|
+
# "Infinity" or "NaN" which are not valid JSON.
|
106
|
+
def as_json(options = nil) #:nodoc:
|
107
|
+
finite? ? self : nil
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
class BigDecimal
|
112
|
+
# A BigDecimal would be naturally represented as a JSON number. Most libraries,
|
113
|
+
# however, parse non-integer JSON numbers directly as floats. Clients using
|
114
|
+
# those libraries would get in general a wrong number and no way to recover
|
115
|
+
# other than manually inspecting the string with the JSON code itself.
|
116
|
+
#
|
117
|
+
# That's why a JSON string is returned. The JSON literal is not numeric, but
|
118
|
+
# if the other end knows by contract that the data is supposed to be a
|
119
|
+
# BigDecimal, it still has the chance to post-process the string and get the
|
120
|
+
# real value.
|
121
|
+
def as_json(options = nil) #:nodoc:
|
122
|
+
finite? ? to_s : nil
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
class Regexp
|
127
|
+
def as_json(options = nil) #:nodoc:
|
128
|
+
to_s
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
module Enumerable
|
133
|
+
def as_json(options = nil) #:nodoc:
|
134
|
+
to_a.as_json(options)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
class IO
|
139
|
+
def as_json(options = nil) #:nodoc:
|
140
|
+
to_s
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
class Range
|
145
|
+
def as_json(options = nil) #:nodoc:
|
146
|
+
to_s
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
class Array
|
151
|
+
def as_json(options = nil) #:nodoc:
|
152
|
+
map { |v| options ? v.as_json(options.dup) : v.as_json }
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
class Hash
|
157
|
+
def as_json(options = nil) #:nodoc:
|
158
|
+
# create a subset of the hash by applying :only or :except
|
159
|
+
subset = if options
|
160
|
+
if attrs = options[:only]
|
161
|
+
slice(*Array(attrs))
|
162
|
+
elsif attrs = options[:except]
|
163
|
+
except(*Array(attrs))
|
164
|
+
else
|
165
|
+
self
|
166
|
+
end
|
167
|
+
else
|
168
|
+
self
|
169
|
+
end
|
170
|
+
|
171
|
+
Hash[subset.map { |k, v| [k.to_s, options ? v.as_json(options.dup) : v.as_json] }]
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
class Time
|
176
|
+
def as_json(options = nil) #:nodoc:
|
177
|
+
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
178
|
+
xmlschema(ActiveSupport::JSON::Encoding.time_precision)
|
179
|
+
else
|
180
|
+
%(#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)})
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
class Date
|
186
|
+
def as_json(options = nil) #:nodoc:
|
187
|
+
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
188
|
+
strftime("%Y-%m-%d")
|
189
|
+
else
|
190
|
+
strftime("%Y/%m/%d")
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
class DateTime
|
196
|
+
def as_json(options = nil) #:nodoc:
|
197
|
+
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
198
|
+
xmlschema(ActiveSupport::JSON::Encoding.time_precision)
|
199
|
+
else
|
200
|
+
strftime("%Y/%m/%d %H:%M:%S %z")
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
class URI::Generic #:nodoc:
|
206
|
+
def as_json(options = nil)
|
207
|
+
to_s
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
class Pathname #:nodoc:
|
212
|
+
def as_json(options = nil)
|
213
|
+
to_s
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
class Process::Status #:nodoc:
|
218
|
+
def as_json(options = nil)
|
219
|
+
{ exitstatus: exitstatus, pid: pid }
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
class Exception
|
224
|
+
def as_json(options = nil)
|
225
|
+
to_s
|
226
|
+
end
|
227
|
+
end
|
@@ -1,3 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cgi"
|
4
|
+
|
1
5
|
class Object
|
2
6
|
# Alias of <tt>to_s</tt>.
|
3
7
|
def to_param
|
@@ -7,7 +11,6 @@ class Object
|
|
7
11
|
# Converts an object into a string suitable for use as a URL query string,
|
8
12
|
# using the given <tt>key</tt> as the param name.
|
9
13
|
def to_query(key)
|
10
|
-
require 'cgi' unless defined?(CGI) && defined?(CGI::escape)
|
11
14
|
"#{CGI.escape(key.to_param)}=#{CGI.escape(to_param.to_s)}"
|
12
15
|
end
|
13
16
|
end
|
@@ -37,7 +40,7 @@ class Array
|
|
37
40
|
# Calls <tt>to_param</tt> on all its elements and joins the result with
|
38
41
|
# slashes. This is used by <tt>url_for</tt> in Action Pack.
|
39
42
|
def to_param
|
40
|
-
collect
|
43
|
+
collect(&:to_param).join "/"
|
41
44
|
end
|
42
45
|
|
43
46
|
# Converts an array into a string suitable for use as a URL query string,
|
@@ -46,7 +49,12 @@ class Array
|
|
46
49
|
# ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
|
47
50
|
def to_query(key)
|
48
51
|
prefix = "#{key}[]"
|
49
|
-
|
52
|
+
|
53
|
+
if empty?
|
54
|
+
nil.to_query(prefix)
|
55
|
+
else
|
56
|
+
collect { |value| value.to_query(prefix) }.join "&"
|
57
|
+
end
|
50
58
|
end
|
51
59
|
end
|
52
60
|
|
@@ -57,19 +65,24 @@ class Hash
|
|
57
65
|
# {name: 'David', nationality: 'Danish'}.to_query
|
58
66
|
# # => "name=David&nationality=Danish"
|
59
67
|
#
|
60
|
-
# An optional namespace can be passed to enclose
|
68
|
+
# An optional namespace can be passed to enclose key names:
|
61
69
|
#
|
62
70
|
# {name: 'David', nationality: 'Danish'}.to_query('user')
|
63
|
-
# # => "user
|
71
|
+
# # => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"
|
64
72
|
#
|
65
73
|
# The string pairs "key=value" that conform the query string
|
66
74
|
# are sorted lexicographically in ascending order.
|
67
75
|
#
|
68
76
|
# This method is also aliased as +to_param+.
|
69
77
|
def to_query(namespace = nil)
|
70
|
-
collect do |key, value|
|
71
|
-
value.
|
72
|
-
|
78
|
+
query = collect do |key, value|
|
79
|
+
unless (value.is_a?(Hash) || value.is_a?(Array)) && value.empty?
|
80
|
+
value.to_query(namespace ? "#{namespace}[#{key}]" : key)
|
81
|
+
end
|
82
|
+
end.compact
|
83
|
+
|
84
|
+
query.sort! unless namespace.to_s.include?("[]")
|
85
|
+
query.join("&")
|
73
86
|
end
|
74
87
|
|
75
88
|
alias_method :to_param, :to_query
|