activesupport 3.2.22.5 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +364 -135
- data/MIT-LICENSE +1 -1
- data/README.rdoc +6 -4
- data/lib/active_support/backtrace_cleaner.rb +33 -25
- data/lib/active_support/basic_object.rb +7 -17
- data/lib/active_support/benchmarkable.rb +19 -15
- data/lib/active_support/buffered_logger.rb +9 -113
- data/lib/active_support/cache/file_store.rb +14 -14
- data/lib/active_support/cache/mem_cache_store.rb +24 -30
- data/lib/active_support/cache/memory_store.rb +2 -0
- data/lib/active_support/cache/strategy/local_cache.rb +48 -37
- data/lib/active_support/cache.rb +228 -183
- data/lib/active_support/callbacks.rb +201 -253
- data/lib/active_support/concern.rb +16 -23
- data/lib/active_support/concurrency/latch.rb +27 -0
- data/lib/active_support/configurable.rb +69 -12
- data/lib/active_support/core_ext/array/access.rb +17 -9
- data/lib/active_support/core_ext/array/conversions.rb +115 -55
- data/lib/active_support/core_ext/array/extract_options.rb +2 -2
- data/lib/active_support/core_ext/array/grouping.rb +21 -22
- data/lib/active_support/core_ext/array/uniq_by.rb +12 -9
- data/lib/active_support/core_ext/array/wrap.rb +13 -16
- data/lib/active_support/core_ext/array.rb +0 -1
- data/lib/active_support/core_ext/benchmark.rb +7 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -24
- data/lib/active_support/core_ext/class/attribute.rb +40 -32
- data/lib/active_support/core_ext/class/attribute_accessors.rb +14 -12
- data/lib/active_support/core_ext/class/delegating_attributes.rb +15 -19
- data/lib/active_support/core_ext/class/subclasses.rb +11 -5
- data/lib/active_support/core_ext/date/calculations.rb +44 -187
- data/lib/active_support/core_ext/date/conversions.rb +16 -38
- data/lib/active_support/core_ext/date/zones.rb +25 -2
- data/lib/active_support/core_ext/date.rb +5 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +232 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +0 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +77 -62
- data/lib/active_support/core_ext/date_time/conversions.rb +21 -33
- data/lib/active_support/core_ext/date_time/zones.rb +11 -8
- data/lib/active_support/core_ext/date_time.rb +4 -0
- data/lib/active_support/core_ext/enumerable.rb +26 -73
- data/lib/active_support/core_ext/file/atomic.rb +27 -11
- data/lib/active_support/core_ext/file.rb +0 -1
- data/lib/active_support/core_ext/hash/conversions.rb +145 -79
- data/lib/active_support/core_ext/hash/deep_merge.rb +14 -8
- data/lib/active_support/core_ext/hash/diff.rb +5 -4
- data/lib/active_support/core_ext/hash/except.rb +1 -9
- data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -5
- data/lib/active_support/core_ext/hash/keys.rb +108 -24
- data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -3
- data/lib/active_support/core_ext/hash/slice.rb +12 -12
- data/lib/active_support/core_ext/hash.rb +0 -1
- data/lib/active_support/core_ext/integer/inflections.rb +13 -1
- data/lib/active_support/core_ext/integer/time.rb +17 -12
- data/lib/active_support/core_ext/kernel/debugger.rb +2 -2
- data/lib/active_support/core_ext/kernel/reporting.rb +36 -22
- data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -7
- data/lib/active_support/core_ext/load_error.rb +7 -5
- data/lib/active_support/core_ext/logger.rb +7 -23
- data/lib/active_support/core_ext/marshal.rb +21 -0
- data/lib/active_support/core_ext/module/aliasing.rb +8 -9
- data/lib/active_support/core_ext/module/anonymous.rb +2 -7
- data/lib/active_support/core_ext/module/attr_internal.rb +0 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +12 -10
- data/lib/active_support/core_ext/module/delegation.rb +92 -49
- data/lib/active_support/core_ext/module/deprecation.rb +19 -3
- data/lib/active_support/core_ext/module/introspection.rb +17 -27
- data/lib/active_support/core_ext/module/qualified_const.rb +8 -20
- data/lib/active_support/core_ext/module/remove_method.rb +1 -5
- data/lib/active_support/core_ext/module.rb +1 -3
- data/lib/active_support/core_ext/numeric/conversions.rb +135 -0
- data/lib/active_support/core_ext/numeric/time.rb +6 -6
- data/lib/active_support/core_ext/numeric.rb +1 -0
- data/lib/active_support/core_ext/object/acts_like.rb +4 -4
- data/lib/active_support/core_ext/object/blank.rb +7 -23
- data/lib/active_support/core_ext/object/deep_dup.rb +46 -0
- data/lib/active_support/core_ext/object/duplicable.rb +1 -30
- data/lib/active_support/core_ext/object/inclusion.rb +8 -7
- data/lib/active_support/core_ext/object/instance_variables.rb +7 -12
- data/lib/active_support/core_ext/object/to_json.rb +8 -0
- data/lib/active_support/core_ext/object/to_param.rb +5 -2
- data/lib/active_support/core_ext/object/try.rb +46 -25
- data/lib/active_support/core_ext/object/with_options.rb +7 -8
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/proc.rb +3 -0
- data/lib/active_support/core_ext/range/conversions.rb +0 -2
- data/lib/active_support/core_ext/range/include_range.rb +3 -1
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/range.rb +0 -2
- data/lib/active_support/core_ext/string/access.rb +95 -90
- data/lib/active_support/core_ext/string/conversions.rb +27 -38
- data/lib/active_support/core_ext/string/encoding.rb +6 -9
- data/lib/active_support/core_ext/string/filters.rb +24 -18
- data/lib/active_support/core_ext/string/indent.rb +43 -0
- data/lib/active_support/core_ext/string/inflections.rb +70 -60
- data/lib/active_support/core_ext/string/inquiry.rb +2 -2
- data/lib/active_support/core_ext/string/multibyte.rb +41 -64
- data/lib/active_support/core_ext/string/output_safety.rb +59 -51
- data/lib/active_support/core_ext/string/zones.rb +13 -0
- data/lib/active_support/core_ext/string.rb +2 -3
- data/lib/active_support/core_ext/struct.rb +6 -0
- data/lib/active_support/core_ext/thread.rb +74 -0
- data/lib/active_support/core_ext/time/calculations.rb +108 -184
- data/lib/active_support/core_ext/time/conversions.rb +27 -51
- data/lib/active_support/core_ext/time/marshal.rb +0 -27
- data/lib/active_support/core_ext/time/zones.rb +27 -17
- data/lib/active_support/core_ext/time.rb +5 -0
- data/lib/active_support/core_ext/uri.rb +13 -17
- data/lib/active_support/core_ext.rb +3 -2
- data/lib/active_support/dependencies/autoload.rb +47 -20
- data/lib/active_support/dependencies.rb +160 -141
- data/lib/active_support/deprecation/behaviors.rb +44 -30
- data/lib/active_support/deprecation/instance_delegator.rb +24 -0
- data/lib/active_support/deprecation/method_wrappers.rb +33 -18
- data/lib/active_support/deprecation/proxy_wrappers.rb +58 -13
- data/lib/active_support/deprecation/reporting.rb +40 -11
- data/lib/active_support/deprecation.rb +39 -14
- data/lib/active_support/descendants_tracker.rb +34 -19
- data/lib/active_support/duration.rb +6 -8
- data/lib/active_support/file_update_checker.rb +63 -47
- data/lib/active_support/gzip.rb +11 -5
- data/lib/active_support/hash_with_indifferent_access.rb +127 -42
- data/lib/active_support/i18n.rb +4 -0
- data/lib/active_support/i18n_railtie.rb +5 -22
- data/lib/active_support/inflections.rb +14 -12
- data/lib/active_support/inflector/inflections.rb +108 -71
- data/lib/active_support/inflector/methods.rb +181 -160
- data/lib/active_support/inflector/transliterate.rb +16 -17
- data/lib/active_support/json/decoding.rb +18 -17
- data/lib/active_support/json/encoding.rb +93 -39
- data/lib/active_support/json/variable.rb +10 -1
- data/lib/active_support/key_generator.rb +75 -0
- data/lib/active_support/lazy_load_hooks.rb +21 -19
- data/lib/active_support/locale/en.yml +100 -3
- data/lib/active_support/log_subscriber/test_helper.rb +18 -15
- data/lib/active_support/log_subscriber.rb +35 -52
- data/lib/active_support/logger.rb +57 -0
- data/lib/active_support/logger_silence.rb +24 -0
- data/lib/active_support/message_encryptor.rb +38 -35
- data/lib/active_support/message_verifier.rb +9 -15
- data/lib/active_support/multibyte/chars.rb +80 -333
- data/lib/active_support/multibyte/unicode.rb +74 -64
- data/lib/active_support/multibyte.rb +5 -28
- data/lib/active_support/notifications/fanout.rb +112 -18
- data/lib/active_support/notifications/instrumenter.rb +33 -14
- data/lib/active_support/notifications.rb +79 -26
- data/lib/active_support/number_helper.rb +637 -0
- data/lib/active_support/ordered_hash.rb +8 -190
- data/lib/active_support/ordered_options.rb +21 -23
- data/lib/active_support/per_thread_registry.rb +52 -0
- data/lib/active_support/proxy_object.rb +13 -0
- data/lib/active_support/rails.rb +27 -0
- data/lib/active_support/railtie.rb +12 -32
- data/lib/active_support/rescuable.rb +9 -4
- data/lib/active_support/string_inquirer.rb +13 -8
- data/lib/active_support/subscriber.rb +93 -0
- data/lib/active_support/tagged_logging.rb +51 -73
- data/lib/active_support/test_case.rb +46 -17
- data/lib/active_support/testing/assertions.rb +56 -26
- data/lib/active_support/testing/autorun.rb +5 -0
- data/lib/active_support/testing/constant_lookup.rb +54 -0
- data/lib/active_support/testing/declarative.rb +1 -1
- data/lib/active_support/testing/deprecation.rb +0 -19
- data/lib/active_support/testing/isolation.rb +29 -58
- data/lib/active_support/testing/pending.rb +5 -43
- data/lib/active_support/testing/setup_and_teardown.rb +6 -92
- data/lib/active_support/testing/tagged_logging.rb +25 -0
- data/lib/active_support/time.rb +6 -21
- data/lib/active_support/time_with_zone.rb +80 -43
- data/lib/active_support/values/time_zone.rb +81 -60
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +7 -6
- data/lib/active_support/xml_mini/jdom.rb +9 -11
- data/lib/active_support/xml_mini/libxml.rb +1 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +2 -3
- data/lib/active_support/xml_mini/nokogiri.rb +1 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +2 -3
- data/lib/active_support/xml_mini/rexml.rb +6 -8
- data/lib/active_support/xml_mini.rb +35 -17
- data/lib/active_support.rb +8 -21
- metadata +104 -72
- data/lib/active_support/base64.rb +0 -54
- data/lib/active_support/core_ext/array/random_access.rb +0 -30
- data/lib/active_support/core_ext/date/freeze.rb +0 -33
- 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 -18
- data/lib/active_support/core_ext/io.rb +0 -15
- data/lib/active_support/core_ext/module/method_names.rb +0 -14
- data/lib/active_support/core_ext/module/synchronization.rb +0 -45
- 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/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/memoizable.rb +0 -116
- 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/security_utils.rb +0 -27
- data/lib/active_support/testing/mochaing.rb +0 -7
- 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 -24
|
@@ -1,21 +1,26 @@
|
|
|
1
|
+
require 'active_support/duration'
|
|
2
|
+
require 'active_support/core_ext/numeric/time'
|
|
3
|
+
|
|
1
4
|
class Integer
|
|
2
|
-
# Enables the use of time calculations and declarations, like 45.minutes +
|
|
5
|
+
# Enables the use of time calculations and declarations, like <tt>45.minutes +
|
|
6
|
+
# 2.hours + 4.years</tt>.
|
|
3
7
|
#
|
|
4
|
-
# These methods use Time#advance for precise date calculations when using
|
|
5
|
-
# as well as adding or subtracting their
|
|
8
|
+
# These methods use Time#advance for precise date calculations when using
|
|
9
|
+
# <tt>from_now</tt>, +ago+, etc. as well as adding or subtracting their
|
|
10
|
+
# results from a Time object.
|
|
6
11
|
#
|
|
7
|
-
# # equivalent to Time.now.advance(:
|
|
12
|
+
# # equivalent to Time.now.advance(months: 1)
|
|
8
13
|
# 1.month.from_now
|
|
9
14
|
#
|
|
10
|
-
# # equivalent to Time.now.advance(:
|
|
15
|
+
# # equivalent to Time.now.advance(years: 2)
|
|
11
16
|
# 2.years.from_now
|
|
12
17
|
#
|
|
13
|
-
# # equivalent to Time.now.advance(:
|
|
18
|
+
# # equivalent to Time.now.advance(months: 4, years: 5)
|
|
14
19
|
# (4.months + 5.years).from_now
|
|
15
20
|
#
|
|
16
|
-
# While these methods provide precise calculation when used as in the examples
|
|
17
|
-
# should be taken to note that this is not true if the result of
|
|
18
|
-
# converted before use:
|
|
21
|
+
# While these methods provide precise calculation when used as in the examples
|
|
22
|
+
# above, care should be taken to note that this is not true if the result of
|
|
23
|
+
# +months+, +years+, etc is converted before use:
|
|
19
24
|
#
|
|
20
25
|
# # equivalent to 30.days.to_i.from_now
|
|
21
26
|
# 1.month.to_i.from_now
|
|
@@ -24,9 +29,9 @@ class Integer
|
|
|
24
29
|
# 1.year.to_f.from_now
|
|
25
30
|
#
|
|
26
31
|
# In such cases, Ruby's core
|
|
27
|
-
# Date[http://
|
|
28
|
-
# Time[http://
|
|
29
|
-
# date and time arithmetic
|
|
32
|
+
# Date[http://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html] and
|
|
33
|
+
# Time[http://ruby-doc.org/stdlib/libdoc/time/rdoc/Time.html] should be used for precision
|
|
34
|
+
# date and time arithmetic.
|
|
30
35
|
def months
|
|
31
36
|
ActiveSupport::Duration.new(self * 30.days, [[:months, self]])
|
|
32
37
|
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
module Kernel
|
|
2
2
|
unless respond_to?(:debugger)
|
|
3
|
-
# Starts a debugging session if
|
|
3
|
+
# Starts a debugging session if the +debugger+ gem has been loaded (call rails server --debugger to do load it).
|
|
4
4
|
def debugger
|
|
5
|
-
message = "\n***** Debugger requested, but was not available (ensure
|
|
5
|
+
message = "\n***** Debugger requested, but was not available (ensure the debugger gem is listed in Gemfile/installed as gem): Start server with --debugger to enable *****\n"
|
|
6
6
|
defined?(Rails) ? Rails.logger.info(message) : $stderr.puts(message)
|
|
7
7
|
end
|
|
8
8
|
alias breakpoint debugger unless respond_to?(:breakpoint)
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
require 'rbconfig'
|
|
2
|
-
require '
|
|
2
|
+
require 'tempfile'
|
|
3
3
|
|
|
4
4
|
module Kernel
|
|
5
|
-
# Sets $VERBOSE to nil for the duration of the block and back to its original
|
|
5
|
+
# Sets $VERBOSE to nil for the duration of the block and back to its original
|
|
6
|
+
# value afterwards.
|
|
6
7
|
#
|
|
7
8
|
# silence_warnings do
|
|
8
9
|
# value = noisy_call # no warning voiced
|
|
@@ -13,12 +14,14 @@ module Kernel
|
|
|
13
14
|
with_warnings(nil) { yield }
|
|
14
15
|
end
|
|
15
16
|
|
|
16
|
-
# Sets $VERBOSE to true for the duration of the block and back to its
|
|
17
|
+
# Sets $VERBOSE to +true+ for the duration of the block and back to its
|
|
18
|
+
# original value afterwards.
|
|
17
19
|
def enable_warnings
|
|
18
20
|
with_warnings(true) { yield }
|
|
19
21
|
end
|
|
20
22
|
|
|
21
|
-
# Sets $VERBOSE for the duration of the block and back to its original
|
|
23
|
+
# Sets $VERBOSE for the duration of the block and back to its original
|
|
24
|
+
# value afterwards.
|
|
22
25
|
def with_warnings(flag)
|
|
23
26
|
old_verbose, $VERBOSE = $VERBOSE, flag
|
|
24
27
|
yield
|
|
@@ -51,40 +54,51 @@ module Kernel
|
|
|
51
54
|
#
|
|
52
55
|
# suppress(ZeroDivisionError) do
|
|
53
56
|
# 1/0
|
|
54
|
-
# puts
|
|
57
|
+
# puts 'This code is NOT reached'
|
|
55
58
|
# end
|
|
56
59
|
#
|
|
57
|
-
# puts
|
|
60
|
+
# puts 'This code gets executed and nothing related to ZeroDivisionError was seen'
|
|
58
61
|
def suppress(*exception_classes)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
end
|
|
62
|
+
yield
|
|
63
|
+
rescue Exception => e
|
|
64
|
+
raise unless exception_classes.any? { |cls| e.kind_of?(cls) }
|
|
63
65
|
end
|
|
64
66
|
|
|
65
67
|
# Captures the given stream and returns it:
|
|
66
68
|
#
|
|
67
|
-
# stream = capture(:stdout) { puts
|
|
68
|
-
# stream # => "
|
|
69
|
+
# stream = capture(:stdout) { puts 'notice' }
|
|
70
|
+
# stream # => "notice\n"
|
|
71
|
+
#
|
|
72
|
+
# stream = capture(:stderr) { warn 'error' }
|
|
73
|
+
# stream # => "error\n"
|
|
74
|
+
#
|
|
75
|
+
# even for subprocesses:
|
|
76
|
+
#
|
|
77
|
+
# stream = capture(:stdout) { system('echo notice') }
|
|
78
|
+
# stream # => "notice\n"
|
|
69
79
|
#
|
|
80
|
+
# stream = capture(:stderr) { system('echo error 1>&2') }
|
|
81
|
+
# stream # => "error\n"
|
|
70
82
|
def capture(stream)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
end
|
|
83
|
+
stream = stream.to_s
|
|
84
|
+
captured_stream = Tempfile.new(stream)
|
|
85
|
+
stream_io = eval("$#{stream}")
|
|
86
|
+
origin_stream = stream_io.dup
|
|
87
|
+
stream_io.reopen(captured_stream)
|
|
88
|
+
|
|
89
|
+
yield
|
|
79
90
|
|
|
80
|
-
|
|
91
|
+
stream_io.rewind
|
|
92
|
+
return captured_stream.read
|
|
93
|
+
ensure
|
|
94
|
+
captured_stream.unlink
|
|
95
|
+
stream_io.reopen(origin_stream)
|
|
81
96
|
end
|
|
82
97
|
alias :silence :capture
|
|
83
98
|
|
|
84
99
|
# Silences both STDOUT and STDERR, even for subprocesses.
|
|
85
100
|
#
|
|
86
101
|
# quietly { system 'bundle install' }
|
|
87
|
-
#
|
|
88
102
|
def quietly
|
|
89
103
|
silence_stream(STDOUT) do
|
|
90
104
|
silence_stream(STDERR) do
|
|
@@ -1,11 +1,4 @@
|
|
|
1
1
|
module Kernel
|
|
2
|
-
# Returns the object's singleton class.
|
|
3
|
-
def singleton_class
|
|
4
|
-
class << self
|
|
5
|
-
self
|
|
6
|
-
end
|
|
7
|
-
end unless respond_to?(:singleton_class) # exists in 1.9.2
|
|
8
|
-
|
|
9
2
|
# class_eval on an object acts like singleton_class.class_eval.
|
|
10
3
|
def class_eval(*args, &block)
|
|
11
4
|
singleton_class.class_eval(*args, &block)
|
|
@@ -6,12 +6,14 @@ class LoadError
|
|
|
6
6
|
/^cannot load such file -- (.+)$/i,
|
|
7
7
|
]
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
unless method_defined?(:path)
|
|
10
|
+
def path
|
|
11
|
+
@path ||= begin
|
|
12
|
+
REGEXPS.find do |regex|
|
|
13
|
+
message =~ regex
|
|
14
|
+
end
|
|
15
|
+
$1
|
|
13
16
|
end
|
|
14
|
-
$1
|
|
15
17
|
end
|
|
16
18
|
end
|
|
17
19
|
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
require 'active_support/core_ext/class/attribute_accessors'
|
|
2
2
|
require 'active_support/deprecation'
|
|
3
|
+
require 'active_support/logger_silence'
|
|
4
|
+
|
|
5
|
+
ActiveSupport::Deprecation.warn 'this file is deprecated and will be removed'
|
|
3
6
|
|
|
4
7
|
# Adds the 'around_level' method to Logger.
|
|
5
8
|
class Logger #:nodoc:
|
|
@@ -29,34 +32,15 @@ require 'logger'
|
|
|
29
32
|
#
|
|
30
33
|
# logger.datetime_format = "%Y-%m-%d"
|
|
31
34
|
#
|
|
32
|
-
# Note: This logger is deprecated in favor of ActiveSupport::
|
|
35
|
+
# Note: This logger is deprecated in favor of ActiveSupport::Logger
|
|
33
36
|
class Logger
|
|
34
|
-
|
|
35
|
-
# :singleton-method:
|
|
36
|
-
# Set to false to disable the silencer
|
|
37
|
-
cattr_accessor :silencer
|
|
38
|
-
self.silencer = true
|
|
39
|
-
|
|
40
|
-
# Silences the logger for the duration of the block.
|
|
41
|
-
def silence(temporary_level = Logger::ERROR)
|
|
42
|
-
if silencer
|
|
43
|
-
begin
|
|
44
|
-
old_logger_level, self.level = level, temporary_level
|
|
45
|
-
yield self
|
|
46
|
-
ensure
|
|
47
|
-
self.level = old_logger_level
|
|
48
|
-
end
|
|
49
|
-
else
|
|
50
|
-
yield self
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
deprecate :silence
|
|
37
|
+
include LoggerSilence
|
|
54
38
|
|
|
55
39
|
alias :old_datetime_format= :datetime_format=
|
|
56
40
|
# Logging date-time format (string passed to +strftime+). Ignored if the formatter
|
|
57
41
|
# does not respond to datetime_format=.
|
|
58
|
-
def datetime_format=(
|
|
59
|
-
formatter.datetime_format =
|
|
42
|
+
def datetime_format=(format)
|
|
43
|
+
formatter.datetime_format = format if formatter.respond_to?(:datetime_format=)
|
|
60
44
|
end
|
|
61
45
|
|
|
62
46
|
alias :old_datetime_format :datetime_format
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'active_support/core_ext/module/aliasing'
|
|
2
|
+
|
|
3
|
+
module Marshal
|
|
4
|
+
class << self
|
|
5
|
+
def load_with_autoloading(source)
|
|
6
|
+
load_without_autoloading(source)
|
|
7
|
+
rescue ArgumentError, NameError => exc
|
|
8
|
+
if exc.message.match(%r|undefined class/module (.+)|)
|
|
9
|
+
# try loading the class/module
|
|
10
|
+
$1.constantize
|
|
11
|
+
# if it is a IO we need to go back to read the object
|
|
12
|
+
source.rewind if source.respond_to?(:rewind)
|
|
13
|
+
retry
|
|
14
|
+
else
|
|
15
|
+
raise exc
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
alias_method_chain :load, :autoloading
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -26,26 +26,25 @@ class Module
|
|
|
26
26
|
aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
|
|
27
27
|
yield(aliased_target, punctuation) if block_given?
|
|
28
28
|
|
|
29
|
-
with_method
|
|
29
|
+
with_method = "#{aliased_target}_with_#{feature}#{punctuation}"
|
|
30
|
+
without_method = "#{aliased_target}_without_#{feature}#{punctuation}"
|
|
30
31
|
|
|
31
32
|
alias_method without_method, target
|
|
32
33
|
alias_method target, with_method
|
|
33
34
|
|
|
34
35
|
case
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
when public_method_defined?(without_method)
|
|
37
|
+
public target
|
|
38
|
+
when protected_method_defined?(without_method)
|
|
39
|
+
protected target
|
|
40
|
+
when private_method_defined?(without_method)
|
|
41
|
+
private target
|
|
41
42
|
end
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
# Allows you to make aliases for attributes, which includes
|
|
45
46
|
# getter, setter, and query methods.
|
|
46
47
|
#
|
|
47
|
-
# Example:
|
|
48
|
-
#
|
|
49
48
|
# class Content < ActiveRecord::Base
|
|
50
49
|
# # has a title attribute
|
|
51
50
|
# end
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'active_support/core_ext/object/blank'
|
|
2
|
-
|
|
3
1
|
class Module
|
|
4
2
|
# A module may or may not have a name.
|
|
5
3
|
#
|
|
@@ -7,7 +5,7 @@ class Module
|
|
|
7
5
|
# M.name # => "M"
|
|
8
6
|
#
|
|
9
7
|
# m = Module.new
|
|
10
|
-
# m.name # =>
|
|
8
|
+
# m.name # => nil
|
|
11
9
|
#
|
|
12
10
|
# A module gets a name when it is first assigned to a constant. Either
|
|
13
11
|
# via the +module+ or +class+ keyword or by an explicit assignment:
|
|
@@ -15,10 +13,7 @@ class Module
|
|
|
15
13
|
# m = Module.new # creates an anonymous module
|
|
16
14
|
# M = m # => m gets a name here as a side-effect
|
|
17
15
|
# m.name # => "M"
|
|
18
|
-
#
|
|
19
16
|
def anonymous?
|
|
20
|
-
|
|
21
|
-
# string in 1.8, and nil in 1.9.
|
|
22
|
-
name.blank?
|
|
17
|
+
name.nil?
|
|
23
18
|
end
|
|
24
19
|
end
|
|
@@ -4,6 +4,7 @@ class Module
|
|
|
4
4
|
def mattr_reader(*syms)
|
|
5
5
|
options = syms.extract_options!
|
|
6
6
|
syms.each do |sym|
|
|
7
|
+
raise NameError.new('invalid attribute name') unless sym =~ /^[_A-Za-z]\w*$/
|
|
7
8
|
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
|
8
9
|
@@#{sym} = nil unless defined? @@#{sym}
|
|
9
10
|
|
|
@@ -25,6 +26,7 @@ class Module
|
|
|
25
26
|
def mattr_writer(*syms)
|
|
26
27
|
options = syms.extract_options!
|
|
27
28
|
syms.each do |sym|
|
|
29
|
+
raise NameError.new('invalid attribute name') unless sym =~ /^[_A-Za-z]\w*$/
|
|
28
30
|
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
|
29
31
|
def self.#{sym}=(obj)
|
|
30
32
|
@@#{sym} = obj
|
|
@@ -44,19 +46,19 @@ class Module
|
|
|
44
46
|
# Extends the module object with module and instance accessors for class attributes,
|
|
45
47
|
# just like the native attr* accessors for instance attributes.
|
|
46
48
|
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
# self.google_api_key = "123456789"
|
|
49
|
+
# module AppConfiguration
|
|
50
|
+
# mattr_accessor :google_api_key
|
|
50
51
|
#
|
|
51
|
-
#
|
|
52
|
-
#
|
|
53
|
-
# end
|
|
52
|
+
# self.google_api_key = "123456789"
|
|
53
|
+
# end
|
|
54
54
|
#
|
|
55
|
-
#
|
|
55
|
+
# AppConfiguration.google_api_key # => "123456789"
|
|
56
|
+
# AppConfiguration.google_api_key = "overriding the api key!"
|
|
57
|
+
# AppConfiguration.google_api_key # => "overriding the api key!"
|
|
56
58
|
#
|
|
57
|
-
# To opt out of the instance writer method, pass :
|
|
58
|
-
# To opt out of the instance reader method, pass :
|
|
59
|
-
# To opt out of both instance methods, pass :
|
|
59
|
+
# To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
|
|
60
|
+
# To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
|
|
61
|
+
# To opt out of both instance methods, pass <tt>instance_accessor: false</tt>.
|
|
60
62
|
def mattr_accessor(*syms)
|
|
61
63
|
mattr_reader(*syms)
|
|
62
64
|
mattr_writer(*syms)
|
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
class Module
|
|
2
|
-
# Provides a delegate class method to easily expose contained objects'
|
|
3
|
-
# as your own.
|
|
4
|
-
#
|
|
5
|
-
#
|
|
2
|
+
# Provides a +delegate+ class method to easily expose contained objects'
|
|
3
|
+
# public methods as your own.
|
|
4
|
+
#
|
|
5
|
+
# The macro receives one or more method names (specified as symbols or
|
|
6
|
+
# strings) and the name of the target object via the <tt>:to</tt> option
|
|
7
|
+
# (also a symbol or string).
|
|
6
8
|
#
|
|
7
9
|
# Delegation is particularly useful with Active Record associations:
|
|
8
10
|
#
|
|
9
11
|
# class Greeter < ActiveRecord::Base
|
|
10
12
|
# def hello
|
|
11
|
-
#
|
|
13
|
+
# 'hello'
|
|
12
14
|
# end
|
|
13
15
|
#
|
|
14
16
|
# def goodbye
|
|
15
|
-
#
|
|
17
|
+
# 'goodbye'
|
|
16
18
|
# end
|
|
17
19
|
# end
|
|
18
20
|
#
|
|
19
21
|
# class Foo < ActiveRecord::Base
|
|
20
22
|
# belongs_to :greeter
|
|
21
|
-
# delegate :hello, :
|
|
23
|
+
# delegate :hello, to: :greeter
|
|
22
24
|
# end
|
|
23
25
|
#
|
|
24
26
|
# Foo.new.hello # => "hello"
|
|
@@ -28,7 +30,7 @@ class Module
|
|
|
28
30
|
#
|
|
29
31
|
# class Foo < ActiveRecord::Base
|
|
30
32
|
# belongs_to :greeter
|
|
31
|
-
# delegate :hello, :goodbye, :
|
|
33
|
+
# delegate :hello, :goodbye, to: :greeter
|
|
32
34
|
# end
|
|
33
35
|
#
|
|
34
36
|
# Foo.new.goodbye # => "goodbye"
|
|
@@ -43,15 +45,27 @@ class Module
|
|
|
43
45
|
# def initialize
|
|
44
46
|
# @instance_array = [8,9,10,11]
|
|
45
47
|
# end
|
|
46
|
-
# delegate :sum, :
|
|
47
|
-
# delegate :min, :
|
|
48
|
-
# delegate :max, :
|
|
48
|
+
# delegate :sum, to: :CONSTANT_ARRAY
|
|
49
|
+
# delegate :min, to: :@@class_array
|
|
50
|
+
# delegate :max, to: :@instance_array
|
|
49
51
|
# end
|
|
50
52
|
#
|
|
51
53
|
# Foo.new.sum # => 6
|
|
52
54
|
# Foo.new.min # => 4
|
|
53
55
|
# Foo.new.max # => 11
|
|
54
56
|
#
|
|
57
|
+
# It's also possible to delegate a method to the class by using +:class+:
|
|
58
|
+
#
|
|
59
|
+
# class Foo
|
|
60
|
+
# def self.hello
|
|
61
|
+
# "world"
|
|
62
|
+
# end
|
|
63
|
+
#
|
|
64
|
+
# delegate :hello, to: :class
|
|
65
|
+
# end
|
|
66
|
+
#
|
|
67
|
+
# Foo.new.hello # => "world"
|
|
68
|
+
#
|
|
55
69
|
# Delegates can optionally be prefixed using the <tt>:prefix</tt> option. If the value
|
|
56
70
|
# is <tt>true</tt>, the delegate methods are prefixed with the name of the object being
|
|
57
71
|
# delegated to.
|
|
@@ -59,10 +73,10 @@ class Module
|
|
|
59
73
|
# Person = Struct.new(:name, :address)
|
|
60
74
|
#
|
|
61
75
|
# class Invoice < Struct.new(:client)
|
|
62
|
-
# delegate :name, :address, :
|
|
76
|
+
# delegate :name, :address, to: :client, prefix: true
|
|
63
77
|
# end
|
|
64
78
|
#
|
|
65
|
-
# john_doe = Person.new(
|
|
79
|
+
# john_doe = Person.new('John Doe', 'Vimmersvej 13')
|
|
66
80
|
# invoice = Invoice.new(john_doe)
|
|
67
81
|
# invoice.client_name # => "John Doe"
|
|
68
82
|
# invoice.client_address # => "Vimmersvej 13"
|
|
@@ -70,49 +84,64 @@ class Module
|
|
|
70
84
|
# It is also possible to supply a custom prefix.
|
|
71
85
|
#
|
|
72
86
|
# class Invoice < Struct.new(:client)
|
|
73
|
-
# delegate :name, :address, :
|
|
87
|
+
# delegate :name, :address, to: :client, prefix: :customer
|
|
74
88
|
# end
|
|
75
89
|
#
|
|
76
90
|
# invoice = Invoice.new(john_doe)
|
|
77
|
-
# invoice.customer_name # =>
|
|
78
|
-
# invoice.customer_address # =>
|
|
91
|
+
# invoice.customer_name # => 'John Doe'
|
|
92
|
+
# invoice.customer_address # => 'Vimmersvej 13'
|
|
93
|
+
#
|
|
94
|
+
# If the target is +nil+ and does not respond to the delegated method a
|
|
95
|
+
# +NoMethodError+ is raised, as with any other value. Sometimes, however, it
|
|
96
|
+
# makes sense to be robust to that situation and that is the purpose of the
|
|
97
|
+
# <tt>:allow_nil</tt> option: If the target is not +nil+, or it is and
|
|
98
|
+
# responds to the method, everything works as usual. But if it is +nil+ and
|
|
99
|
+
# does not respond to the delegated method, +nil+ is returned.
|
|
100
|
+
#
|
|
101
|
+
# class User < ActiveRecord::Base
|
|
102
|
+
# has_one :profile
|
|
103
|
+
# delegate :age, to: :profile
|
|
104
|
+
# end
|
|
105
|
+
#
|
|
106
|
+
# User.new.age # raises NoMethodError: undefined method `age'
|
|
79
107
|
#
|
|
80
|
-
#
|
|
81
|
-
#
|
|
82
|
-
# +nil+ instead with the +:allow_nil+ option.
|
|
108
|
+
# But if not having a profile yet is fine and should not be an error
|
|
109
|
+
# condition:
|
|
83
110
|
#
|
|
84
|
-
#
|
|
85
|
-
#
|
|
86
|
-
#
|
|
87
|
-
#
|
|
88
|
-
#
|
|
89
|
-
#
|
|
90
|
-
#
|
|
111
|
+
# class User < ActiveRecord::Base
|
|
112
|
+
# has_one :profile
|
|
113
|
+
# delegate :age, to: :profile, allow_nil: true
|
|
114
|
+
# end
|
|
115
|
+
#
|
|
116
|
+
# User.new.age # nil
|
|
117
|
+
#
|
|
118
|
+
# Note that if the target is not +nil+ then the call is attempted regardless of the
|
|
119
|
+
# <tt>:allow_nil</tt> option, and thus an exception is still raised if said object
|
|
120
|
+
# does not respond to the method:
|
|
91
121
|
#
|
|
92
|
-
#
|
|
122
|
+
# class Foo
|
|
123
|
+
# def initialize(bar)
|
|
124
|
+
# @bar = bar
|
|
125
|
+
# end
|
|
93
126
|
#
|
|
94
|
-
#
|
|
95
|
-
#
|
|
96
|
-
# def initialize(bar = nil)
|
|
97
|
-
# @bar = bar
|
|
98
|
-
# end
|
|
99
|
-
# delegate :zoo, :to => :bar, :allow_nil => true
|
|
100
|
-
# end
|
|
127
|
+
# delegate :name, to: :@bar, allow_nil: true
|
|
128
|
+
# end
|
|
101
129
|
#
|
|
102
|
-
#
|
|
130
|
+
# Foo.new("Bar").name # raises NoMethodError: undefined method `name'
|
|
103
131
|
#
|
|
104
132
|
def delegate(*methods)
|
|
105
133
|
options = methods.pop
|
|
106
134
|
unless options.is_a?(Hash) && to = options[:to]
|
|
107
|
-
raise ArgumentError,
|
|
135
|
+
raise ArgumentError, 'Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, to: :greeter).'
|
|
108
136
|
end
|
|
109
|
-
prefix, to, allow_nil = options[:prefix], options[:to], options[:allow_nil]
|
|
110
137
|
|
|
111
|
-
|
|
112
|
-
|
|
138
|
+
prefix, allow_nil = options.values_at(:prefix, :allow_nil)
|
|
139
|
+
|
|
140
|
+
if prefix == true && to =~ /^[^a-z_]/
|
|
141
|
+
raise ArgumentError, 'Can only automatically set the delegation prefix when delegating to a method.'
|
|
113
142
|
end
|
|
114
143
|
|
|
115
|
-
method_prefix =
|
|
144
|
+
method_prefix = \
|
|
116
145
|
if prefix
|
|
117
146
|
"#{prefix == true ? to : prefix}_"
|
|
118
147
|
else
|
|
@@ -122,25 +151,39 @@ class Module
|
|
|
122
151
|
file, line = caller.first.split(':', 2)
|
|
123
152
|
line = line.to_i
|
|
124
153
|
|
|
154
|
+
to = to.to_s
|
|
155
|
+
to = 'self.class' if to == 'class'
|
|
156
|
+
|
|
125
157
|
methods.each do |method|
|
|
126
|
-
|
|
158
|
+
# Attribute writer methods only accept one argument. Makes sure []=
|
|
159
|
+
# methods still accept two arguments.
|
|
160
|
+
definition = (method =~ /[^\]]=$/) ? 'arg' : '*args, &block'
|
|
127
161
|
|
|
162
|
+
# The following generated methods call the target exactly once, storing
|
|
163
|
+
# the returned value in a dummy variable.
|
|
164
|
+
#
|
|
165
|
+
# Reason is twofold: On one hand doing less calls is in general better.
|
|
166
|
+
# On the other hand it could be that the target has side-effects,
|
|
167
|
+
# whereas conceptualy, from the user point of view, the delegator should
|
|
168
|
+
# be doing one call.
|
|
128
169
|
if allow_nil
|
|
129
|
-
module_eval(<<-EOS, file, line -
|
|
130
|
-
def #{method_prefix}#{method}(
|
|
131
|
-
|
|
132
|
-
|
|
170
|
+
module_eval(<<-EOS, file, line - 3)
|
|
171
|
+
def #{method_prefix}#{method}(#{definition}) # def customer_name(*args, &block)
|
|
172
|
+
_ = #{to} # _ = client
|
|
173
|
+
if !_.nil? || nil.respond_to?(:#{method}) # if !_.nil? || nil.respond_to?(:name)
|
|
174
|
+
_.#{method}(#{definition}) # _.name(*args, &block)
|
|
133
175
|
end # end
|
|
134
176
|
end # end
|
|
135
177
|
EOS
|
|
136
178
|
else
|
|
137
179
|
exception = %(raise "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
|
|
138
180
|
|
|
139
|
-
module_eval(<<-EOS, file, line -
|
|
140
|
-
def #{method_prefix}#{method}(
|
|
141
|
-
#{to}
|
|
181
|
+
module_eval(<<-EOS, file, line - 2)
|
|
182
|
+
def #{method_prefix}#{method}(#{definition}) # def customer_name(*args, &block)
|
|
183
|
+
_ = #{to} # _ = client
|
|
184
|
+
_.#{method}(#{definition}) # _.name(*args, &block)
|
|
142
185
|
rescue NoMethodError # rescue NoMethodError
|
|
143
|
-
if
|
|
186
|
+
if _.nil? # if _.nil?
|
|
144
187
|
#{exception} # # add helpful message to the exception
|
|
145
188
|
else # else
|
|
146
189
|
raise # raise
|
|
@@ -1,8 +1,24 @@
|
|
|
1
|
+
require 'active_support/deprecation/method_wrappers'
|
|
2
|
+
|
|
1
3
|
class Module
|
|
2
|
-
# Declare that a method has been deprecated.
|
|
3
4
|
# deprecate :foo
|
|
4
|
-
# deprecate :
|
|
5
|
-
# deprecate :foo, :bar, :
|
|
5
|
+
# deprecate bar: 'message'
|
|
6
|
+
# deprecate :foo, :bar, baz: 'warning!', qux: 'gone!'
|
|
7
|
+
#
|
|
8
|
+
# You can also use custom deprecator instance:
|
|
9
|
+
#
|
|
10
|
+
# deprecate :foo, deprecator: MyLib::Deprecator.new
|
|
11
|
+
# deprecate :foo, bar: "warning!", deprecator: MyLib::Deprecator.new
|
|
12
|
+
#
|
|
13
|
+
# \Custom deprecators must respond to <tt>deprecation_warning(deprecated_method_name, message, caller_backtrace)</tt>
|
|
14
|
+
# method where you can implement your custom warning behavior.
|
|
15
|
+
#
|
|
16
|
+
# class MyLib::Deprecator
|
|
17
|
+
# def deprecation_warning(deprecated_method_name, message, caller_backtrace = nil)
|
|
18
|
+
# message = "#{deprecated_method_name} is deprecated and will be removed from MyLibrary | #{message}"
|
|
19
|
+
# Kernel.warn message
|
|
20
|
+
# end
|
|
21
|
+
# end
|
|
6
22
|
def deprecate(*method_names)
|
|
7
23
|
ActiveSupport::Deprecation.deprecate_methods(self, *method_names)
|
|
8
24
|
end
|