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
@@ -0,0 +1,205 @@
|
|
1
|
+
# Hack to load json gem first so we can overwrite its to_json.
|
2
|
+
require 'json'
|
3
|
+
require 'bigdecimal'
|
4
|
+
require 'active_support/core_ext/big_decimal/conversions' # for #to_s
|
5
|
+
require 'active_support/core_ext/hash/except'
|
6
|
+
require 'active_support/core_ext/hash/slice'
|
7
|
+
require 'active_support/core_ext/object/instance_variables'
|
8
|
+
require 'time'
|
9
|
+
require 'active_support/core_ext/time/conversions'
|
10
|
+
require 'active_support/core_ext/date_time/conversions'
|
11
|
+
require 'active_support/core_ext/date/conversions'
|
12
|
+
|
13
|
+
# The JSON gem adds a few modules to Ruby core classes containing :to_json definition, overwriting
|
14
|
+
# their default behavior. That said, we need to define the basic to_json method in all of them,
|
15
|
+
# otherwise they will always use to_json gem implementation, which is backwards incompatible in
|
16
|
+
# several cases (for instance, the JSON implementation for Hash does not work) with inheritance
|
17
|
+
# and consequently classes as ActiveSupport::OrderedHash cannot be serialized to json.
|
18
|
+
#
|
19
|
+
# On the other hand, we should avoid conflict with ::JSON.{generate,dump}(obj). Unfortunately, the
|
20
|
+
# JSON gem's encoder relies on its own to_json implementation to encode objects. Since it always
|
21
|
+
# passes a ::JSON::State object as the only argument to to_json, we can detect that and forward the
|
22
|
+
# calls to the original to_json method.
|
23
|
+
#
|
24
|
+
# It should be noted that when using ::JSON.{generate,dump} directly, ActiveSupport's encoder is
|
25
|
+
# bypassed completely. This means that as_json won't be invoked and the JSON gem will simply
|
26
|
+
# ignore any options it does not natively understand. This also means that ::JSON.{generate,dump}
|
27
|
+
# should give exactly the same results with or without active support.
|
28
|
+
|
29
|
+
module ActiveSupport
|
30
|
+
module ToJsonWithActiveSupportEncoder # :nodoc:
|
31
|
+
def to_json(options = nil)
|
32
|
+
if options.is_a?(::JSON::State)
|
33
|
+
# Called from JSON.{generate,dump}, forward it to JSON gem's to_json
|
34
|
+
super(options)
|
35
|
+
else
|
36
|
+
# to_json is being invoked directly, use ActiveSupport's encoder
|
37
|
+
ActiveSupport::JSON.encode(self, options)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
[Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass, Enumerable].reverse_each do |klass|
|
44
|
+
klass.prepend(ActiveSupport::ToJsonWithActiveSupportEncoder)
|
45
|
+
end
|
46
|
+
|
47
|
+
class Object
|
48
|
+
def as_json(options = nil) #:nodoc:
|
49
|
+
if respond_to?(:to_hash)
|
50
|
+
to_hash.as_json(options)
|
51
|
+
else
|
52
|
+
instance_values.as_json(options)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class Struct #:nodoc:
|
58
|
+
def as_json(options = nil)
|
59
|
+
Hash[members.zip(values)].as_json(options)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class TrueClass
|
64
|
+
def as_json(options = nil) #:nodoc:
|
65
|
+
self
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class FalseClass
|
70
|
+
def as_json(options = nil) #:nodoc:
|
71
|
+
self
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
class NilClass
|
76
|
+
def as_json(options = nil) #:nodoc:
|
77
|
+
self
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class String
|
82
|
+
def as_json(options = nil) #:nodoc:
|
83
|
+
self
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class Symbol
|
88
|
+
def as_json(options = nil) #:nodoc:
|
89
|
+
to_s
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class Numeric
|
94
|
+
def as_json(options = nil) #:nodoc:
|
95
|
+
self
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class Float
|
100
|
+
# Encoding Infinity or NaN to JSON should return "null". The default returns
|
101
|
+
# "Infinity" or "NaN" which are not valid JSON.
|
102
|
+
def as_json(options = nil) #:nodoc:
|
103
|
+
finite? ? self : nil
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
class BigDecimal
|
108
|
+
# A BigDecimal would be naturally represented as a JSON number. Most libraries,
|
109
|
+
# however, parse non-integer JSON numbers directly as floats. Clients using
|
110
|
+
# those libraries would get in general a wrong number and no way to recover
|
111
|
+
# other than manually inspecting the string with the JSON code itself.
|
112
|
+
#
|
113
|
+
# That's why a JSON string is returned. The JSON literal is not numeric, but
|
114
|
+
# if the other end knows by contract that the data is supposed to be a
|
115
|
+
# BigDecimal, it still has the chance to post-process the string and get the
|
116
|
+
# real value.
|
117
|
+
def as_json(options = nil) #:nodoc:
|
118
|
+
finite? ? to_s : nil
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
class Regexp
|
123
|
+
def as_json(options = nil) #:nodoc:
|
124
|
+
to_s
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
module Enumerable
|
129
|
+
def as_json(options = nil) #:nodoc:
|
130
|
+
to_a.as_json(options)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
class Range
|
135
|
+
def as_json(options = nil) #:nodoc:
|
136
|
+
to_s
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
class Array
|
141
|
+
def as_json(options = nil) #:nodoc:
|
142
|
+
map { |v| options ? v.as_json(options.dup) : v.as_json }
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
class Hash
|
147
|
+
def as_json(options = nil) #:nodoc:
|
148
|
+
# create a subset of the hash by applying :only or :except
|
149
|
+
subset = if options
|
150
|
+
if attrs = options[:only]
|
151
|
+
slice(*Array(attrs))
|
152
|
+
elsif attrs = options[:except]
|
153
|
+
except(*Array(attrs))
|
154
|
+
else
|
155
|
+
self
|
156
|
+
end
|
157
|
+
else
|
158
|
+
self
|
159
|
+
end
|
160
|
+
|
161
|
+
Hash[subset.map { |k, v| [k.to_s, options ? v.as_json(options.dup) : v.as_json] }]
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
class Time
|
166
|
+
def as_json(options = nil) #:nodoc:
|
167
|
+
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
168
|
+
xmlschema(ActiveSupport::JSON::Encoding.time_precision)
|
169
|
+
else
|
170
|
+
%(#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)})
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
class Date
|
176
|
+
def as_json(options = nil) #:nodoc:
|
177
|
+
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
178
|
+
strftime("%Y-%m-%d")
|
179
|
+
else
|
180
|
+
strftime("%Y/%m/%d")
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
class DateTime
|
186
|
+
def as_json(options = nil) #:nodoc:
|
187
|
+
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
188
|
+
xmlschema(ActiveSupport::JSON::Encoding.time_precision)
|
189
|
+
else
|
190
|
+
strftime('%Y/%m/%d %H:%M:%S %z')
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
class Process::Status #:nodoc:
|
196
|
+
def as_json(options = nil)
|
197
|
+
{ :exitstatus => exitstatus, :pid => pid }
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
class Exception
|
202
|
+
def as_json(options = nil)
|
203
|
+
to_s
|
204
|
+
end
|
205
|
+
end
|
@@ -1,55 +1 @@
|
|
1
|
-
|
2
|
-
# Alias of <tt>to_s</tt>.
|
3
|
-
def to_param
|
4
|
-
to_s
|
5
|
-
end
|
6
|
-
end
|
7
|
-
|
8
|
-
class NilClass
|
9
|
-
def to_param
|
10
|
-
self
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
class TrueClass
|
15
|
-
def to_param
|
16
|
-
self
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
class FalseClass
|
21
|
-
def to_param
|
22
|
-
self
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
class Array
|
27
|
-
# Calls <tt>to_param</tt> on all its elements and joins the result with
|
28
|
-
# slashes. This is used by <tt>url_for</tt> in Action Pack.
|
29
|
-
def to_param
|
30
|
-
collect { |e| e.to_param }.join '/'
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
class Hash
|
35
|
-
# Returns a string representation of the receiver suitable for use as a URL
|
36
|
-
# query string:
|
37
|
-
#
|
38
|
-
# {:name => 'David', :nationality => 'Danish'}.to_param
|
39
|
-
# # => "name=David&nationality=Danish"
|
40
|
-
#
|
41
|
-
# An optional namespace can be passed to enclose the param names:
|
42
|
-
#
|
43
|
-
# {:name => 'David', :nationality => 'Danish'}.to_param('user')
|
44
|
-
# # => "user[name]=David&user[nationality]=Danish"
|
45
|
-
#
|
46
|
-
# The string pairs "key=value" that conform the query string
|
47
|
-
# are sorted lexicographically in ascending order.
|
48
|
-
#
|
49
|
-
# This method is also aliased as +to_query+.
|
50
|
-
def to_param(namespace = nil)
|
51
|
-
collect do |key, value|
|
52
|
-
value.to_query(namespace ? "#{namespace}[#{key}]" : key)
|
53
|
-
end.sort * '&'
|
54
|
-
end
|
55
|
-
end
|
1
|
+
require 'active_support/core_ext/object/to_query'
|
@@ -1,27 +1,84 @@
|
|
1
|
-
require '
|
1
|
+
require 'cgi'
|
2
2
|
|
3
3
|
class Object
|
4
|
-
#
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
# Alias of <tt>to_s</tt>.
|
5
|
+
def to_param
|
6
|
+
to_s
|
7
|
+
end
|
8
|
+
|
9
|
+
# Converts an object into a string suitable for use as a URL query string,
|
10
|
+
# using the given <tt>key</tt> as the param name.
|
8
11
|
def to_query(key)
|
9
|
-
|
10
|
-
|
12
|
+
"#{CGI.escape(key.to_param)}=#{CGI.escape(to_param.to_s)}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class NilClass
|
17
|
+
# Returns +self+.
|
18
|
+
def to_param
|
19
|
+
self
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class TrueClass
|
24
|
+
# Returns +self+.
|
25
|
+
def to_param
|
26
|
+
self
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class FalseClass
|
31
|
+
# Returns +self+.
|
32
|
+
def to_param
|
33
|
+
self
|
11
34
|
end
|
12
35
|
end
|
13
36
|
|
14
37
|
class Array
|
38
|
+
# Calls <tt>to_param</tt> on all its elements and joins the result with
|
39
|
+
# slashes. This is used by <tt>url_for</tt> in Action Pack.
|
40
|
+
def to_param
|
41
|
+
collect(&:to_param).join '/'
|
42
|
+
end
|
43
|
+
|
15
44
|
# Converts an array into a string suitable for use as a URL query string,
|
16
45
|
# using the given +key+ as the param name.
|
17
46
|
#
|
18
47
|
# ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
|
19
48
|
def to_query(key)
|
20
49
|
prefix = "#{key}[]"
|
21
|
-
|
50
|
+
|
51
|
+
if empty?
|
52
|
+
nil.to_query(prefix)
|
53
|
+
else
|
54
|
+
collect { |value| value.to_query(prefix) }.join '&'
|
55
|
+
end
|
22
56
|
end
|
23
57
|
end
|
24
58
|
|
25
59
|
class Hash
|
26
|
-
|
60
|
+
# Returns a string representation of the receiver suitable for use as a URL
|
61
|
+
# query string:
|
62
|
+
#
|
63
|
+
# {name: 'David', nationality: 'Danish'}.to_query
|
64
|
+
# # => "name=David&nationality=Danish"
|
65
|
+
#
|
66
|
+
# An optional namespace can be passed to enclose key names:
|
67
|
+
#
|
68
|
+
# {name: 'David', nationality: 'Danish'}.to_query('user')
|
69
|
+
# # => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"
|
70
|
+
#
|
71
|
+
# The string pairs "key=value" that conform the query string
|
72
|
+
# are sorted lexicographically in ascending order.
|
73
|
+
#
|
74
|
+
# This method is also aliased as +to_param+.
|
75
|
+
def to_query(namespace = nil)
|
76
|
+
collect do |key, value|
|
77
|
+
unless (value.is_a?(Hash) || value.is_a?(Array)) && value.empty?
|
78
|
+
value.to_query(namespace ? "#{namespace}[#{key}]" : key)
|
79
|
+
end
|
80
|
+
end.compact.sort! * '&'
|
81
|
+
end
|
82
|
+
|
83
|
+
alias_method :to_param, :to_query
|
27
84
|
end
|
@@ -1,55 +1,146 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
module Tryable #:nodoc:
|
5
|
+
def try(*a, &b)
|
6
|
+
try!(*a, &b) if a.empty? || respond_to?(a.first)
|
7
|
+
end
|
8
|
+
|
9
|
+
def try!(*a, &b)
|
10
|
+
if a.empty? && block_given?
|
11
|
+
if b.arity == 0
|
12
|
+
instance_eval(&b)
|
13
|
+
else
|
14
|
+
yield self
|
15
|
+
end
|
16
|
+
else
|
17
|
+
public_send(*a, &b)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
1
23
|
class Object
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
#
|
6
|
-
# and +nil+ will be returned instead, if the receiving object is a +nil+ object or NilClass.
|
24
|
+
include ActiveSupport::Tryable
|
25
|
+
|
26
|
+
##
|
27
|
+
# :method: try
|
7
28
|
#
|
8
|
-
#
|
29
|
+
# :call-seq:
|
30
|
+
# try(*a, &b)
|
9
31
|
#
|
10
|
-
#
|
32
|
+
# Invokes the public method whose name goes as first argument just like
|
33
|
+
# +public_send+ does, except that if the receiver does not respond to it the
|
34
|
+
# call returns +nil+ rather than raising an exception.
|
11
35
|
#
|
12
|
-
#
|
13
|
-
# @person && @person.name
|
14
|
-
# or
|
15
|
-
# @person ? @person.name : nil
|
36
|
+
# This method is defined to be able to write
|
16
37
|
#
|
17
|
-
# With +try+
|
18
38
|
# @person.try(:name)
|
19
39
|
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
# @
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
|
27
|
-
#
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
40
|
+
# instead of
|
41
|
+
#
|
42
|
+
# @person.name if @person
|
43
|
+
#
|
44
|
+
# +try+ calls can be chained:
|
45
|
+
#
|
46
|
+
# @person.try(:spouse).try(:name)
|
47
|
+
#
|
48
|
+
# instead of
|
49
|
+
#
|
50
|
+
# @person.spouse.name if @person && @person.spouse
|
51
|
+
#
|
52
|
+
# +try+ will also return +nil+ if the receiver does not respond to the method:
|
53
|
+
#
|
54
|
+
# @person.try(:non_existing_method) # => nil
|
55
|
+
#
|
56
|
+
# instead of
|
57
|
+
#
|
58
|
+
# @person.non_existing_method if @person.respond_to?(:non_existing_method) # => nil
|
59
|
+
#
|
60
|
+
# +try+ returns +nil+ when called on +nil+ regardless of whether it responds
|
61
|
+
# to the method:
|
62
|
+
#
|
63
|
+
# nil.try(:to_i) # => nil, rather than 0
|
64
|
+
#
|
65
|
+
# Arguments and blocks are forwarded to the method if invoked:
|
66
|
+
#
|
67
|
+
# @posts.try(:each_slice, 2) do |a, b|
|
68
|
+
# ...
|
69
|
+
# end
|
70
|
+
#
|
71
|
+
# The number of arguments in the signature must match. If the object responds
|
72
|
+
# to the method the call is attempted and +ArgumentError+ is still raised
|
73
|
+
# in case of argument mismatch.
|
74
|
+
#
|
75
|
+
# If +try+ is called without arguments it yields the receiver to a given
|
76
|
+
# block unless it is +nil+:
|
77
|
+
#
|
78
|
+
# @person.try do |p|
|
79
|
+
# ...
|
80
|
+
# end
|
81
|
+
#
|
82
|
+
# You can also call try with a block without accepting an argument, and the block
|
83
|
+
# will be instance_eval'ed instead:
|
84
|
+
#
|
85
|
+
# @person.try { upcase.truncate(50) }
|
86
|
+
#
|
87
|
+
# Please also note that +try+ is defined on +Object+. Therefore, it won't work
|
88
|
+
# with instances of classes that do not have +Object+ among their ancestors,
|
89
|
+
# like direct subclasses of +BasicObject+.
|
90
|
+
|
91
|
+
##
|
92
|
+
# :method: try!
|
93
|
+
#
|
94
|
+
# :call-seq:
|
95
|
+
# try!(*a, &b)
|
96
|
+
#
|
97
|
+
# Same as #try, but raises a +NoMethodError+ exception if the receiver is
|
98
|
+
# not +nil+ and does not implement the tried method.
|
99
|
+
#
|
100
|
+
# "a".try!(:upcase) # => "A"
|
101
|
+
# nil.try!(:upcase) # => nil
|
102
|
+
# 123.try!(:upcase) # => NoMethodError: undefined method `upcase' for 123:Integer
|
103
|
+
end
|
104
|
+
|
105
|
+
class Delegator
|
106
|
+
include ActiveSupport::Tryable
|
107
|
+
|
108
|
+
##
|
109
|
+
# :method: try
|
110
|
+
#
|
111
|
+
# :call-seq:
|
112
|
+
# try(a*, &b)
|
113
|
+
#
|
114
|
+
# See Object#try
|
115
|
+
|
116
|
+
##
|
117
|
+
# :method: try!
|
118
|
+
#
|
119
|
+
# :call-seq:
|
120
|
+
# try!(a*, &b)
|
121
|
+
#
|
122
|
+
# See Object#try!
|
37
123
|
end
|
38
124
|
|
39
125
|
class NilClass
|
40
126
|
# Calling +try+ on +nil+ always returns +nil+.
|
41
|
-
# It becomes
|
42
|
-
#
|
43
|
-
# === Examples
|
127
|
+
# It becomes especially helpful when navigating through associations that may return +nil+.
|
44
128
|
#
|
45
129
|
# nil.try(:name) # => nil
|
46
130
|
#
|
47
131
|
# Without +try+
|
48
|
-
# @person &&
|
132
|
+
# @person && @person.children.any? && @person.children.first.name
|
49
133
|
#
|
50
134
|
# With +try+
|
51
135
|
# @person.try(:children).try(:first).try(:name)
|
52
136
|
def try(*args)
|
53
137
|
nil
|
54
138
|
end
|
139
|
+
|
140
|
+
# Calling +try!+ on +nil+ always returns +nil+.
|
141
|
+
#
|
142
|
+
# nil.try!(:name) # => nil
|
143
|
+
def try!(*args)
|
144
|
+
nil
|
145
|
+
end
|
55
146
|
end
|
@@ -7,19 +7,19 @@ class Object
|
|
7
7
|
# provided. Each method called on the block variable must take an options
|
8
8
|
# hash as its final argument.
|
9
9
|
#
|
10
|
-
# Without <tt>with_options
|
10
|
+
# Without <tt>with_options</tt>, this code contains duplication:
|
11
11
|
#
|
12
12
|
# class Account < ActiveRecord::Base
|
13
|
-
# has_many :customers, :
|
14
|
-
# has_many :products, :
|
15
|
-
# has_many :invoices, :
|
16
|
-
# has_many :expenses, :
|
13
|
+
# has_many :customers, dependent: :destroy
|
14
|
+
# has_many :products, dependent: :destroy
|
15
|
+
# has_many :invoices, dependent: :destroy
|
16
|
+
# has_many :expenses, dependent: :destroy
|
17
17
|
# end
|
18
18
|
#
|
19
19
|
# Using <tt>with_options</tt>, we can remove the duplication:
|
20
20
|
#
|
21
21
|
# class Account < ActiveRecord::Base
|
22
|
-
# with_options :
|
22
|
+
# with_options dependent: :destroy do |assoc|
|
23
23
|
# assoc.has_many :customers
|
24
24
|
# assoc.has_many :products
|
25
25
|
# assoc.has_many :invoices
|
@@ -29,15 +29,41 @@ class Object
|
|
29
29
|
#
|
30
30
|
# It can also be used with an explicit receiver:
|
31
31
|
#
|
32
|
-
# I18n.with_options :
|
32
|
+
# I18n.with_options locale: user.locale, scope: 'newsletter' do |i18n|
|
33
33
|
# subject i18n.t :subject
|
34
|
-
# body i18n.t :body, :
|
34
|
+
# body i18n.t :body, user_name: user.name
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# When you don't pass an explicit receiver, it executes the whole block
|
38
|
+
# in merging options context:
|
39
|
+
#
|
40
|
+
# class Account < ActiveRecord::Base
|
41
|
+
# with_options dependent: :destroy do
|
42
|
+
# has_many :customers
|
43
|
+
# has_many :products
|
44
|
+
# has_many :invoices
|
45
|
+
# has_many :expenses
|
46
|
+
# end
|
35
47
|
# end
|
36
48
|
#
|
37
49
|
# <tt>with_options</tt> can also be nested since the call is forwarded to its receiver.
|
38
|
-
# Each nesting level will merge inherited defaults in addition to their own.
|
39
50
|
#
|
40
|
-
|
41
|
-
|
51
|
+
# NOTE: Each nesting level will merge inherited defaults in addition to their own.
|
52
|
+
#
|
53
|
+
# class Post < ActiveRecord::Base
|
54
|
+
# with_options if: :persisted?, length: { minimum: 50 } do
|
55
|
+
# validates :content, if: -> { content.present? }
|
56
|
+
# end
|
57
|
+
# end
|
58
|
+
#
|
59
|
+
# The code is equivalent to:
|
60
|
+
#
|
61
|
+
# validates :content, length: { minimum: 50 }, if: -> { content.present? }
|
62
|
+
#
|
63
|
+
# Hence the inherited default for `if` key is ignored.
|
64
|
+
#
|
65
|
+
def with_options(options, &block)
|
66
|
+
option_merger = ActiveSupport::OptionMerger.new(self, options)
|
67
|
+
block.arity.zero? ? option_merger.instance_eval(&block) : block.call(option_merger)
|
42
68
|
end
|
43
69
|
end
|
@@ -1,13 +1,14 @@
|
|
1
1
|
require 'active_support/core_ext/object/acts_like'
|
2
2
|
require 'active_support/core_ext/object/blank'
|
3
3
|
require 'active_support/core_ext/object/duplicable'
|
4
|
+
require 'active_support/core_ext/object/deep_dup'
|
4
5
|
require 'active_support/core_ext/object/try'
|
5
6
|
require 'active_support/core_ext/object/inclusion'
|
6
7
|
|
7
8
|
require 'active_support/core_ext/object/conversions'
|
8
9
|
require 'active_support/core_ext/object/instance_variables'
|
9
10
|
|
10
|
-
require 'active_support/core_ext/object/
|
11
|
+
require 'active_support/core_ext/object/json'
|
11
12
|
require 'active_support/core_ext/object/to_param'
|
12
13
|
require 'active_support/core_ext/object/to_query'
|
13
14
|
require 'active_support/core_ext/object/with_options'
|
@@ -1,21 +1,31 @@
|
|
1
|
-
|
1
|
+
module ActiveSupport::RangeWithFormat
|
2
2
|
RANGE_FORMATS = {
|
3
3
|
:db => Proc.new { |start, stop| "BETWEEN '#{start.to_s(:db)}' AND '#{stop.to_s(:db)}'" }
|
4
4
|
}
|
5
5
|
|
6
|
-
#
|
6
|
+
# Convert range to a formatted string. See RANGE_FORMATS for predefined formats.
|
7
7
|
#
|
8
|
-
#
|
8
|
+
# range = (1..100) # => 1..100
|
9
9
|
#
|
10
|
-
#
|
11
|
-
|
10
|
+
# range.to_s # => "1..100"
|
11
|
+
# range.to_s(:db) # => "BETWEEN '1' AND '100'"
|
12
|
+
#
|
13
|
+
# == Adding your own range formats to to_s
|
14
|
+
# You can add your own formats to the Range::RANGE_FORMATS hash.
|
15
|
+
# Use the format name as the hash key and a Proc instance.
|
16
|
+
#
|
17
|
+
# # config/initializers/range_formats.rb
|
18
|
+
# Range::RANGE_FORMATS[:short] = ->(start, stop) { "Between #{start.to_s(:db)} and #{stop.to_s(:db)}" }
|
19
|
+
def to_s(format = :default)
|
12
20
|
if formatter = RANGE_FORMATS[format]
|
13
21
|
formatter.call(first, last)
|
14
22
|
else
|
15
|
-
|
23
|
+
super()
|
16
24
|
end
|
17
25
|
end
|
18
26
|
|
19
27
|
alias_method :to_default_s, :to_s
|
20
|
-
alias_method :
|
28
|
+
alias_method :to_formatted_s, :to_s
|
21
29
|
end
|
30
|
+
|
31
|
+
Range.prepend(ActiveSupport::RangeWithFormat)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ActiveSupport
|
2
|
+
module EachTimeWithZone #:nodoc:
|
3
|
+
def each(&block)
|
4
|
+
ensure_iteration_allowed
|
5
|
+
super
|
6
|
+
end
|
7
|
+
|
8
|
+
def step(n = 1, &block)
|
9
|
+
ensure_iteration_allowed
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def ensure_iteration_allowed
|
16
|
+
raise TypeError, "can't iterate from #{first.class}" if first.is_a?(Time)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
Range.prepend(ActiveSupport::EachTimeWithZone)
|