activesupport 3.2.22.5 → 4.0.0.beta1
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 +4 -4
- data/CHANGELOG.md +325 -136
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -2
- data/lib/active_support.rb +8 -21
- 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.rb +203 -171
- data/lib/active_support/cache/file_store.rb +12 -12
- 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/callbacks.rb +195 -247
- 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.rb +1 -0
- data/lib/active_support/core_ext/array.rb +0 -1
- data/lib/active_support/core_ext/array/access.rb +17 -9
- data/lib/active_support/core_ext/array/conversions.rb +113 -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 +11 -14
- data/lib/active_support/core_ext/big_decimal/conversions.rb +7 -24
- data/lib/active_support/core_ext/class/attribute.rb +12 -8
- 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.rb +6 -0
- data/lib/active_support/core_ext/date/calculations.rb +34 -188
- data/lib/active_support/core_ext/date/conversions.rb +16 -38
- data/lib/active_support/core_ext/date/infinite_comparable.rb +5 -0
- data/lib/active_support/core_ext/date/zones.rb +25 -2
- data/lib/active_support/core_ext/date_and_time/calculations.rb +232 -0
- data/lib/active_support/core_ext/date_time.rb +5 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +0 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +73 -65
- data/lib/active_support/core_ext/date_time/conversions.rb +21 -33
- data/lib/active_support/core_ext/date_time/infinite_comparable.rb +5 -0
- data/lib/active_support/core_ext/date_time/zones.rb +11 -8
- data/lib/active_support/core_ext/enumerable.rb +26 -73
- data/lib/active_support/core_ext/file.rb +0 -1
- data/lib/active_support/core_ext/file/atomic.rb +27 -11
- data/lib/active_support/core_ext/hash.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/infinite_comparable.rb +35 -0
- 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 +19 -0
- data/lib/active_support/core_ext/module.rb +1 -3
- 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 +57 -40
- 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/numeric.rb +2 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +135 -0
- data/lib/active_support/core_ext/numeric/infinite_comparable.rb +9 -0
- data/lib/active_support/core_ext/numeric/time.rb +6 -6
- data/lib/active_support/core_ext/object.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 +6 -6
- 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/proc.rb +3 -0
- data/lib/active_support/core_ext/range.rb +0 -2
- data/lib/active_support/core_ext/range/conversions.rb +0 -2
- data/lib/active_support/core_ext/range/include_range.rb +1 -1
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/string.rb +2 -2
- data/lib/active_support/core_ext/string/access.rb +95 -90
- data/lib/active_support/core_ext/string/conversions.rb +29 -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/struct.rb +6 -0
- data/lib/active_support/core_ext/thread.rb +74 -0
- data/lib/active_support/core_ext/time.rb +6 -0
- data/lib/active_support/core_ext/time/calculations.rb +105 -193
- data/lib/active_support/core_ext/time/conversions.rb +27 -51
- data/lib/active_support/core_ext/time/infinite_comparable.rb +5 -0
- 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/uri.rb +13 -17
- data/lib/active_support/dependencies.rb +160 -141
- data/lib/active_support/dependencies/autoload.rb +47 -20
- data/lib/active_support/deprecation.rb +39 -14
- 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/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 +112 -37
- 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.rb +56 -36
- data/lib/active_support/log_subscriber/test_helper.rb +18 -15
- data/lib/active_support/logger.rb +57 -0
- data/lib/active_support/logger_silence.rb +24 -0
- data/lib/active_support/message_encryptor.rb +32 -29
- data/lib/active_support/message_verifier.rb +8 -14
- data/lib/active_support/multibyte.rb +5 -28
- data/lib/active_support/multibyte/chars.rb +80 -333
- data/lib/active_support/multibyte/unicode.rb +74 -64
- data/lib/active_support/notifications.rb +57 -25
- data/lib/active_support/notifications/fanout.rb +105 -18
- data/lib/active_support/notifications/instrumenter.rb +32 -13
- data/lib/active_support/number_helper.rb +636 -0
- data/lib/active_support/ordered_hash.rb +8 -190
- data/lib/active_support/ordered_options.rb +21 -23
- 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/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 +52 -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 +25 -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 +78 -43
- data/lib/active_support/values/time_zone.rb +77 -58
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +4 -4
- data/lib/active_support/xml_mini.rb +35 -17
- data/lib/active_support/xml_mini/jdom.rb +9 -17
- data/lib/active_support/xml_mini/libxml.rb +1 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +1 -2
- data/lib/active_support/xml_mini/nokogiri.rb +1 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -2
- data/lib/active_support/xml_mini/rexml.rb +6 -8
- metadata +107 -77
- 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.rb +0 -1
- data/lib/active_support/core_ext/float/rounding.rb +0 -19
- 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.rb +0 -1
- data/lib/active_support/core_ext/process/daemon.rb +0 -23
- 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/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.rb +0 -317
- 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.rb +0 -152
- 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/time/autoload.rb +0 -5
- data/lib/active_support/whiny_nil.rb +0 -24
@@ -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,19 @@
|
|
1
|
+
module Marshal
|
2
|
+
class << self
|
3
|
+
def load_with_autoloading(source)
|
4
|
+
load_without_autoloading(source)
|
5
|
+
rescue ArgumentError, NameError => exc
|
6
|
+
if exc.message.match(%r|undefined class/module (.+)|)
|
7
|
+
# try loading the class/module
|
8
|
+
$1.constantize
|
9
|
+
# if it is a IO we need to go back to read the object
|
10
|
+
source.rewind if source.respond_to?(:rewind)
|
11
|
+
retry
|
12
|
+
else
|
13
|
+
raise exc
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
alias_method_chain :load, :autoloading
|
18
|
+
end
|
19
|
+
end
|
@@ -5,8 +5,6 @@ require 'active_support/core_ext/module/reachable'
|
|
5
5
|
require 'active_support/core_ext/module/attribute_accessors'
|
6
6
|
require 'active_support/core_ext/module/attr_internal'
|
7
7
|
require 'active_support/core_ext/module/delegation'
|
8
|
-
require 'active_support/core_ext/module/synchronization'
|
9
8
|
require 'active_support/core_ext/module/deprecation'
|
10
9
|
require 'active_support/core_ext/module/remove_method'
|
11
|
-
require 'active_support/core_ext/module/
|
12
|
-
require 'active_support/core_ext/module/qualified_const'
|
10
|
+
require 'active_support/core_ext/module/qualified_const'
|
@@ -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,5 +1,5 @@
|
|
1
1
|
class Module
|
2
|
-
# Provides a delegate class method to easily expose contained objects' methods
|
2
|
+
# Provides a delegate class method to easily expose contained objects' public methods
|
3
3
|
# as your own. Pass one or more methods (specified as symbols or strings)
|
4
4
|
# and the name of the target object via the <tt>:to</tt> option (also a symbol
|
5
5
|
# or string). At least one method and the <tt>:to</tt> option are required.
|
@@ -8,17 +8,17 @@ class Module
|
|
8
8
|
#
|
9
9
|
# class Greeter < ActiveRecord::Base
|
10
10
|
# def hello
|
11
|
-
#
|
11
|
+
# 'hello'
|
12
12
|
# end
|
13
13
|
#
|
14
14
|
# def goodbye
|
15
|
-
#
|
15
|
+
# 'goodbye'
|
16
16
|
# end
|
17
17
|
# end
|
18
18
|
#
|
19
19
|
# class Foo < ActiveRecord::Base
|
20
20
|
# belongs_to :greeter
|
21
|
-
# delegate :hello, :
|
21
|
+
# delegate :hello, to: :greeter
|
22
22
|
# end
|
23
23
|
#
|
24
24
|
# Foo.new.hello # => "hello"
|
@@ -28,7 +28,7 @@ class Module
|
|
28
28
|
#
|
29
29
|
# class Foo < ActiveRecord::Base
|
30
30
|
# belongs_to :greeter
|
31
|
-
# delegate :hello, :goodbye, :
|
31
|
+
# delegate :hello, :goodbye, to: :greeter
|
32
32
|
# end
|
33
33
|
#
|
34
34
|
# Foo.new.goodbye # => "goodbye"
|
@@ -43,15 +43,27 @@ class Module
|
|
43
43
|
# def initialize
|
44
44
|
# @instance_array = [8,9,10,11]
|
45
45
|
# end
|
46
|
-
# delegate :sum, :
|
47
|
-
# delegate :min, :
|
48
|
-
# delegate :max, :
|
46
|
+
# delegate :sum, to: :CONSTANT_ARRAY
|
47
|
+
# delegate :min, to: :@@class_array
|
48
|
+
# delegate :max, to: :@instance_array
|
49
49
|
# end
|
50
50
|
#
|
51
51
|
# Foo.new.sum # => 6
|
52
52
|
# Foo.new.min # => 4
|
53
53
|
# Foo.new.max # => 11
|
54
54
|
#
|
55
|
+
# It's also possible to delegate a method to the class by using +:class+:
|
56
|
+
#
|
57
|
+
# class Foo
|
58
|
+
# def self.hello
|
59
|
+
# "world"
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
# delegate :hello, to: :class
|
63
|
+
# end
|
64
|
+
#
|
65
|
+
# Foo.new.hello # => "world"
|
66
|
+
#
|
55
67
|
# Delegates can optionally be prefixed using the <tt>:prefix</tt> option. If the value
|
56
68
|
# is <tt>true</tt>, the delegate methods are prefixed with the name of the object being
|
57
69
|
# delegated to.
|
@@ -59,10 +71,10 @@ class Module
|
|
59
71
|
# Person = Struct.new(:name, :address)
|
60
72
|
#
|
61
73
|
# class Invoice < Struct.new(:client)
|
62
|
-
# delegate :name, :address, :
|
74
|
+
# delegate :name, :address, to: :client, prefix: true
|
63
75
|
# end
|
64
76
|
#
|
65
|
-
# john_doe = Person.new(
|
77
|
+
# john_doe = Person.new('John Doe', 'Vimmersvej 13')
|
66
78
|
# invoice = Invoice.new(john_doe)
|
67
79
|
# invoice.client_name # => "John Doe"
|
68
80
|
# invoice.client_address # => "Vimmersvej 13"
|
@@ -70,49 +82,49 @@ class Module
|
|
70
82
|
# It is also possible to supply a custom prefix.
|
71
83
|
#
|
72
84
|
# class Invoice < Struct.new(:client)
|
73
|
-
# delegate :name, :address, :
|
85
|
+
# delegate :name, :address, to: :client, prefix: :customer
|
74
86
|
# end
|
75
87
|
#
|
76
88
|
# invoice = Invoice.new(john_doe)
|
77
|
-
# invoice.customer_name # =>
|
78
|
-
# invoice.customer_address # =>
|
89
|
+
# invoice.customer_name # => 'John Doe'
|
90
|
+
# invoice.customer_address # => 'Vimmersvej 13'
|
79
91
|
#
|
80
92
|
# If the delegate object is +nil+ an exception is raised, and that happens
|
81
93
|
# no matter whether +nil+ responds to the delegated method. You can get a
|
82
94
|
# +nil+ instead with the +:allow_nil+ option.
|
83
95
|
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
91
|
-
#
|
92
|
-
# Foo.new.zoo # raises NoMethodError exception (you called nil.zoo)
|
96
|
+
# class Foo
|
97
|
+
# attr_accessor :bar
|
98
|
+
# def initialize(bar = nil)
|
99
|
+
# @bar = bar
|
100
|
+
# end
|
101
|
+
# delegate :zoo, to: :bar
|
102
|
+
# end
|
93
103
|
#
|
94
|
-
#
|
95
|
-
# attr_accessor :bar
|
96
|
-
# def initialize(bar = nil)
|
97
|
-
# @bar = bar
|
98
|
-
# end
|
99
|
-
# delegate :zoo, :to => :bar, :allow_nil => true
|
100
|
-
# end
|
104
|
+
# Foo.new.zoo # raises NoMethodError exception (you called nil.zoo)
|
101
105
|
#
|
102
|
-
#
|
106
|
+
# class Foo
|
107
|
+
# attr_accessor :bar
|
108
|
+
# def initialize(bar = nil)
|
109
|
+
# @bar = bar
|
110
|
+
# end
|
111
|
+
# delegate :zoo, to: :bar, allow_nil: true
|
112
|
+
# end
|
103
113
|
#
|
114
|
+
# Foo.new.zoo # returns nil
|
104
115
|
def delegate(*methods)
|
105
116
|
options = methods.pop
|
106
117
|
unless options.is_a?(Hash) && to = options[:to]
|
107
|
-
raise ArgumentError,
|
118
|
+
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
119
|
end
|
109
|
-
prefix, to, allow_nil = options[:prefix], options[:to], options[:allow_nil]
|
110
120
|
|
111
|
-
|
112
|
-
|
121
|
+
prefix, allow_nil = options.values_at(:prefix, :allow_nil)
|
122
|
+
|
123
|
+
if prefix == true && to =~ /^[^a-z_]/
|
124
|
+
raise ArgumentError, 'Can only automatically set the delegation prefix when delegating to a method.'
|
113
125
|
end
|
114
126
|
|
115
|
-
method_prefix =
|
127
|
+
method_prefix = \
|
116
128
|
if prefix
|
117
129
|
"#{prefix == true ? to : prefix}_"
|
118
130
|
else
|
@@ -122,14 +134,19 @@ class Module
|
|
122
134
|
file, line = caller.first.split(':', 2)
|
123
135
|
line = line.to_i
|
124
136
|
|
137
|
+
to = to.to_s
|
138
|
+
to = 'self.class' if to == 'class'
|
139
|
+
|
125
140
|
methods.each do |method|
|
126
|
-
|
141
|
+
# Attribute writer methods only accept one argument. Makes sure []=
|
142
|
+
# methods still accept two arguments.
|
143
|
+
definition = (method =~ /[^\]]=$/) ? 'arg' : '*args, &block'
|
127
144
|
|
128
145
|
if allow_nil
|
129
146
|
module_eval(<<-EOS, file, line - 2)
|
130
|
-
def #{method_prefix}#{method}(
|
147
|
+
def #{method_prefix}#{method}(#{definition}) # def customer_name(*args, &block)
|
131
148
|
if #{to} || #{to}.respond_to?(:#{method}) # if client || client.respond_to?(:name)
|
132
|
-
#{to}
|
149
|
+
#{to}.#{method}(#{definition}) # client.name(*args, &block)
|
133
150
|
end # end
|
134
151
|
end # end
|
135
152
|
EOS
|
@@ -137,8 +154,8 @@ class Module
|
|
137
154
|
exception = %(raise "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
|
138
155
|
|
139
156
|
module_eval(<<-EOS, file, line - 1)
|
140
|
-
def #{method_prefix}#{method}(
|
141
|
-
#{to}
|
157
|
+
def #{method_prefix}#{method}(#{definition}) # def customer_name(*args, &block)
|
158
|
+
#{to}.#{method}(#{definition}) # client.name(*args, &block)
|
142
159
|
rescue NoMethodError # rescue NoMethodError
|
143
160
|
if #{to}.nil? # if client.nil?
|
144
161
|
#{exception} # # add helpful message to the exception
|