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,16 +1,19 @@
|
|
|
1
1
|
class Array
|
|
2
|
-
#
|
|
2
|
+
# *DEPRECATED*: Use <tt>Array#uniq</tt> instead.
|
|
3
3
|
#
|
|
4
|
-
#
|
|
4
|
+
# Returns a unique array based on the criteria in the block.
|
|
5
5
|
#
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
# [1, 2, 3, 4].uniq_by { |i| i.odd? } # => [1, 2]
|
|
7
|
+
def uniq_by(&block)
|
|
8
|
+
ActiveSupport::Deprecation.warn 'uniq_by is deprecated. Use Array#uniq instead'
|
|
9
|
+
uniq(&block)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
#
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
# *DEPRECATED*: Use <tt>Array#uniq!</tt> instead.
|
|
13
|
+
#
|
|
14
|
+
# Same as +uniq_by+, but modifies +self+.
|
|
15
|
+
def uniq_by!(&block)
|
|
16
|
+
ActiveSupport::Deprecation.warn 'uniq_by! is deprecated. Use Array#uniq! instead'
|
|
17
|
+
uniq!(&block)
|
|
15
18
|
end
|
|
16
19
|
end
|
|
@@ -7,35 +7,32 @@ class Array
|
|
|
7
7
|
# * Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned.
|
|
8
8
|
# * Otherwise, returns an array with the argument as its single element.
|
|
9
9
|
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
10
|
+
# Array.wrap(nil) # => []
|
|
11
|
+
# Array.wrap([1, 2, 3]) # => [1, 2, 3]
|
|
12
|
+
# Array.wrap(0) # => [0]
|
|
13
13
|
#
|
|
14
14
|
# This method is similar in purpose to <tt>Kernel#Array</tt>, but there are some differences:
|
|
15
15
|
#
|
|
16
16
|
# * If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt>
|
|
17
|
-
#
|
|
18
|
-
#
|
|
17
|
+
# moves on to try +to_a+ if the returned value is +nil+, but <tt>Array.wrap</tt> returns
|
|
18
|
+
# +nil+ right away.
|
|
19
19
|
# * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt>
|
|
20
|
-
#
|
|
21
|
-
# * It does not call +to_a+ on the argument,
|
|
20
|
+
# raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value.
|
|
21
|
+
# * It does not call +to_a+ on the argument, but returns an empty array if argument is +nil+.
|
|
22
22
|
#
|
|
23
|
-
# The
|
|
23
|
+
# The second point is easily explained with some enumerables:
|
|
24
24
|
#
|
|
25
|
-
# Array(:
|
|
26
|
-
# Array.wrap(:
|
|
27
|
-
#
|
|
28
|
-
# Array("foo\nbar") # => ["foo\n", "bar"], in Ruby 1.8
|
|
29
|
-
# Array.wrap("foo\nbar") # => ["foo\nbar"]
|
|
25
|
+
# Array(foo: :bar) # => [[:foo, :bar]]
|
|
26
|
+
# Array.wrap(foo: :bar) # => [{:foo=>:bar}]
|
|
30
27
|
#
|
|
31
28
|
# There's also a related idiom that uses the splat operator:
|
|
32
29
|
#
|
|
33
30
|
# [*object]
|
|
34
31
|
#
|
|
35
|
-
# which returns <tt>[
|
|
32
|
+
# which returns <tt>[]</tt> for +nil+, but calls to <tt>Array(object)</tt> otherwise.
|
|
36
33
|
#
|
|
37
|
-
#
|
|
38
|
-
#
|
|
34
|
+
# The differences with <tt>Kernel#Array</tt> explained above
|
|
35
|
+
# apply to the rest of <tt>object</tt>s.
|
|
39
36
|
def self.wrap(object)
|
|
40
37
|
if object.nil?
|
|
41
38
|
[]
|
|
@@ -4,5 +4,4 @@ require 'active_support/core_ext/array/uniq_by'
|
|
|
4
4
|
require 'active_support/core_ext/array/conversions'
|
|
5
5
|
require 'active_support/core_ext/array/extract_options'
|
|
6
6
|
require 'active_support/core_ext/array/grouping'
|
|
7
|
-
require 'active_support/core_ext/array/random_access'
|
|
8
7
|
require 'active_support/core_ext/array/prepend_and_append'
|
|
@@ -1,31 +1,10 @@
|
|
|
1
1
|
require 'bigdecimal'
|
|
2
|
-
|
|
3
|
-
begin
|
|
4
|
-
require 'psych'
|
|
5
|
-
rescue LoadError
|
|
6
|
-
end
|
|
7
|
-
|
|
2
|
+
require 'bigdecimal/util'
|
|
8
3
|
require 'yaml'
|
|
9
4
|
|
|
10
5
|
class BigDecimal
|
|
11
|
-
YAML_TAG = 'tag:yaml.org,2002:float'
|
|
12
6
|
YAML_MAPPING = { 'Infinity' => '.Inf', '-Infinity' => '-.Inf', 'NaN' => '.NaN' }
|
|
13
7
|
|
|
14
|
-
# This emits the number without any scientific notation.
|
|
15
|
-
# This is better than self.to_f.to_s since it doesn't lose precision.
|
|
16
|
-
#
|
|
17
|
-
# Note that reconstituting YAML floats to native floats may lose precision.
|
|
18
|
-
def to_yaml(opts = {})
|
|
19
|
-
return super if
|
|
20
|
-
(defined?(YAML::ENGINE) && !YAML::ENGINE.syck?) ||
|
|
21
|
-
(defined?(Psych) && YAML == Psych)
|
|
22
|
-
|
|
23
|
-
YAML.quick_emit(nil, opts) do |out|
|
|
24
|
-
string = to_s
|
|
25
|
-
out.scalar(YAML_TAG, YAML_MAPPING[string] || string, :plain)
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
8
|
def encode_with(coder)
|
|
30
9
|
string = to_s
|
|
31
10
|
coder.represent_scalar(nil, YAML_MAPPING[string] || string)
|
|
@@ -39,8 +18,13 @@ class BigDecimal
|
|
|
39
18
|
end
|
|
40
19
|
|
|
41
20
|
DEFAULT_STRING_FORMAT = 'F'
|
|
42
|
-
def to_formatted_s(
|
|
43
|
-
|
|
21
|
+
def to_formatted_s(*args)
|
|
22
|
+
if args[0].is_a?(Symbol)
|
|
23
|
+
super
|
|
24
|
+
else
|
|
25
|
+
format = args[0] || DEFAULT_STRING_FORMAT
|
|
26
|
+
_original_to_s(format)
|
|
27
|
+
end
|
|
44
28
|
end
|
|
45
29
|
alias_method :_original_to_s, :to_s
|
|
46
30
|
alias_method :to_s, :to_formatted_s
|
|
@@ -44,7 +44,8 @@ class Class
|
|
|
44
44
|
# Base.setting # => []
|
|
45
45
|
# Subclass.setting # => [:foo]
|
|
46
46
|
#
|
|
47
|
-
# For convenience,
|
|
47
|
+
# For convenience, an instance predicate method is defined as well.
|
|
48
|
+
# To skip it, pass <tt>instance_predicate: false</tt>.
|
|
48
49
|
#
|
|
49
50
|
# Subclass.setting? # => false
|
|
50
51
|
#
|
|
@@ -57,61 +58,68 @@ class Class
|
|
|
57
58
|
# object.setting # => false
|
|
58
59
|
# Base.setting # => true
|
|
59
60
|
#
|
|
60
|
-
# To opt out of the instance reader method, pass :
|
|
61
|
+
# To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
|
|
61
62
|
#
|
|
62
63
|
# object.setting # => NoMethodError
|
|
63
64
|
# object.setting? # => NoMethodError
|
|
64
65
|
#
|
|
65
|
-
# To opt out of the instance writer method, pass :
|
|
66
|
+
# To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
|
|
66
67
|
#
|
|
67
68
|
# object.setting = false # => NoMethodError
|
|
69
|
+
#
|
|
70
|
+
# To opt out of both instance methods, pass <tt>instance_accessor: false</tt>.
|
|
68
71
|
def class_attribute(*attrs)
|
|
69
72
|
options = attrs.extract_options!
|
|
70
|
-
|
|
71
|
-
|
|
73
|
+
# double assignment is used to avoid "assigned but unused variable" warning
|
|
74
|
+
instance_reader = instance_reader = options.fetch(:instance_accessor, true) && options.fetch(:instance_reader, true)
|
|
75
|
+
instance_writer = options.fetch(:instance_accessor, true) && options.fetch(:instance_writer, true)
|
|
76
|
+
instance_predicate = options.fetch(:instance_predicate, true)
|
|
72
77
|
|
|
73
78
|
attrs.each do |name|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def self.#{name}?() !!#{name} end
|
|
79
|
+
define_singleton_method(name) { nil }
|
|
80
|
+
define_singleton_method("#{name}?") { !!public_send(name) } if instance_predicate
|
|
77
81
|
|
|
78
|
-
|
|
79
|
-
singleton_class.class_eval do
|
|
80
|
-
remove_possible_method(:#{name})
|
|
81
|
-
define_method(:#{name}) { val }
|
|
82
|
-
end
|
|
82
|
+
ivar = "@#{name}"
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
84
|
+
define_singleton_method("#{name}=") do |val|
|
|
85
|
+
singleton_class.class_eval do
|
|
86
|
+
remove_possible_method(name)
|
|
87
|
+
define_method(name) { val }
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
if singleton_class?
|
|
91
|
+
class_eval do
|
|
92
|
+
remove_possible_method(name)
|
|
93
|
+
define_method(name) do
|
|
94
|
+
if instance_variable_defined? ivar
|
|
95
|
+
instance_variable_get ivar
|
|
96
|
+
else
|
|
97
|
+
singleton_class.send name
|
|
89
98
|
end
|
|
90
99
|
end
|
|
91
100
|
end
|
|
92
|
-
val
|
|
93
101
|
end
|
|
102
|
+
val
|
|
103
|
+
end
|
|
94
104
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
!!#{name}
|
|
105
|
+
if instance_reader
|
|
106
|
+
remove_possible_method name
|
|
107
|
+
define_method(name) do
|
|
108
|
+
if instance_variable_defined?(ivar)
|
|
109
|
+
instance_variable_get ivar
|
|
110
|
+
else
|
|
111
|
+
self.class.public_send name
|
|
103
112
|
end
|
|
104
113
|
end
|
|
105
|
-
|
|
114
|
+
define_method("#{name}?") { !!public_send(name) } if instance_predicate
|
|
115
|
+
end
|
|
106
116
|
|
|
107
117
|
attr_writer name if instance_writer
|
|
108
118
|
end
|
|
109
119
|
end
|
|
110
120
|
|
|
111
121
|
private
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
ancestors.first != self
|
|
115
|
-
end
|
|
122
|
+
def singleton_class?
|
|
123
|
+
ancestors.first != self
|
|
116
124
|
end
|
|
117
125
|
end
|
|
@@ -21,17 +21,18 @@ class Class
|
|
|
21
21
|
# end
|
|
22
22
|
# # => NameError: invalid attribute name
|
|
23
23
|
#
|
|
24
|
-
# If you want to opt out the instance reader method, you can pass <tt
|
|
25
|
-
# or <tt
|
|
24
|
+
# If you want to opt out the instance reader method, you can pass <tt>instance_reader: false</tt>
|
|
25
|
+
# or <tt>instance_accessor: false</tt>.
|
|
26
26
|
#
|
|
27
27
|
# class Person
|
|
28
|
-
# cattr_reader :hair_colors, :
|
|
28
|
+
# cattr_reader :hair_colors, instance_reader: false
|
|
29
29
|
# end
|
|
30
30
|
#
|
|
31
31
|
# Person.new.hair_colors # => NoMethodError
|
|
32
32
|
def cattr_reader(*syms)
|
|
33
33
|
options = syms.extract_options!
|
|
34
34
|
syms.each do |sym|
|
|
35
|
+
raise NameError.new("invalid class attribute name: #{sym}") unless sym =~ /^[_A-Za-z]\w*$/
|
|
35
36
|
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
|
36
37
|
unless defined? @@#{sym}
|
|
37
38
|
@@#{sym} = nil
|
|
@@ -71,11 +72,11 @@ class Class
|
|
|
71
72
|
# end
|
|
72
73
|
# # => NameError: invalid attribute name
|
|
73
74
|
#
|
|
74
|
-
# If you want to opt out the instance writer method, pass <tt
|
|
75
|
-
# or <tt
|
|
75
|
+
# If you want to opt out the instance writer method, pass <tt>instance_writer: false</tt>
|
|
76
|
+
# or <tt>instance_accessor: false</tt>.
|
|
76
77
|
#
|
|
77
78
|
# class Person
|
|
78
|
-
# cattr_writer :hair_colors, :
|
|
79
|
+
# cattr_writer :hair_colors, instance_writer: false
|
|
79
80
|
# end
|
|
80
81
|
#
|
|
81
82
|
# Person.new.hair_colors = [:blonde, :red] # => NoMethodError
|
|
@@ -92,6 +93,7 @@ class Class
|
|
|
92
93
|
def cattr_writer(*syms)
|
|
93
94
|
options = syms.extract_options!
|
|
94
95
|
syms.each do |sym|
|
|
96
|
+
raise NameError.new("invalid class attribute name: #{sym}") unless sym =~ /^[_A-Za-z]\w*$/
|
|
95
97
|
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
|
96
98
|
unless defined? @@#{sym}
|
|
97
99
|
@@#{sym} = nil
|
|
@@ -109,7 +111,7 @@ class Class
|
|
|
109
111
|
end
|
|
110
112
|
EOS
|
|
111
113
|
end
|
|
112
|
-
|
|
114
|
+
send("#{sym}=", yield) if block_given?
|
|
113
115
|
end
|
|
114
116
|
end
|
|
115
117
|
|
|
@@ -133,20 +135,20 @@ class Class
|
|
|
133
135
|
# Male.hair_colors << :blue
|
|
134
136
|
# Person.hair_colors # => [:brown, :black, :blonde, :red, :blue]
|
|
135
137
|
#
|
|
136
|
-
# To opt out of the instance writer method, pass <tt
|
|
137
|
-
# To opt out of the instance reader method, pass <tt
|
|
138
|
+
# To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
|
|
139
|
+
# To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
|
|
138
140
|
#
|
|
139
141
|
# class Person
|
|
140
|
-
# cattr_accessor :hair_colors, :
|
|
142
|
+
# cattr_accessor :hair_colors, instance_writer: false, instance_reader: false
|
|
141
143
|
# end
|
|
142
144
|
#
|
|
143
145
|
# Person.new.hair_colors = [:brown] # => NoMethodError
|
|
144
146
|
# Person.new.hair_colors # => NoMethodError
|
|
145
147
|
#
|
|
146
|
-
# Or pass <tt
|
|
148
|
+
# Or pass <tt>instance_accessor: false</tt>, to opt out both instance methods.
|
|
147
149
|
#
|
|
148
150
|
# class Person
|
|
149
|
-
# cattr_accessor :hair_colors, :
|
|
151
|
+
# cattr_accessor :hair_colors, instance_accessor: false
|
|
150
152
|
# end
|
|
151
153
|
#
|
|
152
154
|
# Person.new.hair_colors = [:brown] # => NoMethodError
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'active_support/core_ext/object/blank'
|
|
2
|
-
require 'active_support/core_ext/array/extract_options'
|
|
3
1
|
require 'active_support/core_ext/kernel/singleton_class'
|
|
4
2
|
require 'active_support/core_ext/module/remove_method'
|
|
5
3
|
|
|
@@ -22,23 +20,21 @@ class Class
|
|
|
22
20
|
define_method("#{name}?") { !!send("#{name}") } if options[:instance_reader] != false
|
|
23
21
|
end
|
|
24
22
|
|
|
25
|
-
private
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
define_method(method) { object } if instance_reader
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def _superclass_delegating_accessor(name, options = {})
|
|
38
|
-
singleton_class.send(:define_method, "#{name}=") do |value|
|
|
39
|
-
_stash_object_in_method(value, name, options[:instance_reader] != false)
|
|
23
|
+
private
|
|
24
|
+
# Take the object being set and store it in a method. This gives us automatic
|
|
25
|
+
# inheritance behavior, without having to store the object in an instance
|
|
26
|
+
# variable and look up the superclass chain manually.
|
|
27
|
+
def _stash_object_in_method(object, method, instance_reader = true)
|
|
28
|
+
singleton_class.remove_possible_method(method)
|
|
29
|
+
singleton_class.send(:define_method, method) { object }
|
|
30
|
+
remove_possible_method(method)
|
|
31
|
+
define_method(method) { object } if instance_reader
|
|
40
32
|
end
|
|
41
|
-
send("#{name}=", nil)
|
|
42
|
-
end
|
|
43
33
|
|
|
34
|
+
def _superclass_delegating_accessor(name, options = {})
|
|
35
|
+
singleton_class.send(:define_method, "#{name}=") do |value|
|
|
36
|
+
_stash_object_in_method(value, name, options[:instance_reader] != false)
|
|
37
|
+
end
|
|
38
|
+
send("#{name}=", nil)
|
|
39
|
+
end
|
|
44
40
|
end
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
require 'active_support/core_ext/module/anonymous'
|
|
2
2
|
require 'active_support/core_ext/module/reachable'
|
|
3
3
|
|
|
4
|
-
class Class
|
|
4
|
+
class Class
|
|
5
5
|
begin
|
|
6
6
|
ObjectSpace.each_object(Class.new) {}
|
|
7
7
|
|
|
8
|
-
def descendants
|
|
8
|
+
def descendants # :nodoc:
|
|
9
9
|
descendants = []
|
|
10
|
-
ObjectSpace.each_object(
|
|
10
|
+
ObjectSpace.each_object(singleton_class) do |k|
|
|
11
11
|
descendants.unshift k unless k == self
|
|
12
12
|
end
|
|
13
13
|
descendants
|
|
14
14
|
end
|
|
15
15
|
rescue StandardError # JRuby
|
|
16
|
-
def descendants
|
|
16
|
+
def descendants # :nodoc:
|
|
17
17
|
descendants = []
|
|
18
18
|
ObjectSpace.each_object(Class) do |k|
|
|
19
19
|
descendants.unshift k if k < self
|
|
@@ -25,7 +25,13 @@ class Class #:nodoc:
|
|
|
25
25
|
|
|
26
26
|
# Returns an array with the direct children of +self+.
|
|
27
27
|
#
|
|
28
|
-
# Integer.subclasses # => [
|
|
28
|
+
# Integer.subclasses # => [Fixnum, Bignum]
|
|
29
|
+
#
|
|
30
|
+
# class Foo; end
|
|
31
|
+
# class Bar < Foo; end
|
|
32
|
+
# class Baz < Bar; end
|
|
33
|
+
#
|
|
34
|
+
# Foo.subclasses # => [Bar]
|
|
29
35
|
def subclasses
|
|
30
36
|
subclasses, chain = [], descendants
|
|
31
37
|
chain.each do |k|
|