activesupport 4.0.12 → 7.0.2.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +249 -501
- data/MIT-LICENSE +2 -2
- data/README.rdoc +10 -5
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +41 -13
- data/lib/active_support/benchmarkable.rb +7 -15
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache/file_store.rb +96 -74
- data/lib/active_support/cache/mem_cache_store.rb +211 -103
- data/lib/active_support/cache/memory_store.rb +90 -58
- data/lib/active_support/cache/null_store.rb +19 -7
- data/lib/active_support/cache/redis_cache_store.rb +468 -0
- data/lib/active_support/cache/strategy/local_cache.rb +86 -83
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
- data/lib/active_support/cache.rb +580 -241
- data/lib/active_support/callbacks.rb +812 -425
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +103 -14
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +33 -0
- data/lib/active_support/concurrency/share_lock.rb +226 -0
- data/lib/active_support/configurable.rb +21 -19
- data/lib/active_support/configuration_file.rb +51 -0
- data/lib/active_support/core_ext/array/access.rb +47 -1
- data/lib/active_support/core_ext/array/conversions.rb +35 -44
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +26 -16
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/wrap.rb +7 -4
- data/lib/active_support/core_ext/array.rb +10 -7
- data/lib/active_support/core_ext/benchmark.rb +5 -3
- data/lib/active_support/core_ext/big_decimal/conversions.rb +9 -26
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/class/attribute.rb +52 -49
- data/lib/active_support/core_ext/class/attribute_accessors.rb +5 -169
- data/lib/active_support/core_ext/class/subclasses.rb +25 -26
- data/lib/active_support/core_ext/class.rb +4 -4
- data/lib/active_support/core_ext/date/acts_like.rb +3 -1
- data/lib/active_support/core_ext/date/blank.rb +14 -0
- data/lib/active_support/core_ext/date/calculations.rb +31 -18
- data/lib/active_support/core_ext/date/conversions.rb +43 -32
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/date/zones.rb +5 -34
- data/lib/active_support/core_ext/date.rb +7 -4
- data/lib/active_support/core_ext/date_and_time/calculations.rb +198 -66
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +31 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
- data/lib/active_support/core_ext/date_time/blank.rb +14 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +79 -38
- data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +31 -26
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/date_time.rb +8 -4
- data/lib/active_support/core_ext/digest/uuid.rb +79 -0
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +249 -17
- data/lib/active_support/core_ext/file/atomic.rb +41 -32
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +71 -49
- data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +14 -5
- data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
- data/lib/active_support/core_ext/hash/keys.rb +39 -56
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +8 -23
- data/lib/active_support/core_ext/hash.rb +10 -8
- data/lib/active_support/core_ext/integer/inflections.rb +3 -1
- data/lib/active_support/core_ext/integer/multiple.rb +3 -1
- data/lib/active_support/core_ext/integer/time.rb +11 -33
- data/lib/active_support/core_ext/integer.rb +5 -3
- data/lib/active_support/core_ext/kernel/concern.rb +14 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +9 -78
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +5 -4
- data/lib/active_support/core_ext/load_error.rb +5 -21
- data/lib/active_support/core_ext/module/aliasing.rb +6 -44
- data/lib/active_support/core_ext/module/anonymous.rb +12 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +8 -8
- data/lib/active_support/core_ext/module/attribute_accessors.rb +186 -44
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +157 -0
- data/lib/active_support/core_ext/module/concerning.rb +140 -0
- data/lib/active_support/core_ext/module/delegation.rb +172 -45
- data/lib/active_support/core_ext/module/deprecation.rb +3 -3
- data/lib/active_support/core_ext/module/introspection.rb +23 -38
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +8 -3
- data/lib/active_support/core_ext/module.rb +13 -10
- data/lib/active_support/core_ext/name_error.rb +45 -4
- data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +135 -127
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
- data/lib/active_support/core_ext/numeric/time.rb +37 -50
- data/lib/active_support/core_ext/numeric.rb +6 -3
- data/lib/active_support/core_ext/object/acts_like.rb +41 -6
- data/lib/active_support/core_ext/object/blank.rb +70 -20
- data/lib/active_support/core_ext/object/conversions.rb +6 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +19 -10
- data/lib/active_support/core_ext/object/duplicable.rb +17 -47
- data/lib/active_support/core_ext/object/inclusion.rb +18 -15
- data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
- data/lib/active_support/core_ext/object/json.rb +244 -0
- data/lib/active_support/core_ext/object/to_param.rb +3 -1
- data/lib/active_support/core_ext/object/to_query.rb +21 -8
- data/lib/active_support/core_ext/object/try.rb +106 -26
- data/lib/active_support/core_ext/object/with_options.rb +64 -5
- data/lib/active_support/core_ext/object.rb +14 -12
- data/lib/active_support/core_ext/pathname/existence.rb +21 -0
- data/lib/active_support/core_ext/pathname.rb +3 -0
- data/lib/active_support/core_ext/range/compare_range.rb +57 -0
- data/lib/active_support/core_ext/range/conversions.rb +37 -15
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/range/each.rb +18 -17
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +7 -0
- data/lib/active_support/core_ext/range/overlaps.rb +2 -0
- data/lib/active_support/core_ext/range.rb +7 -4
- data/lib/active_support/core_ext/regexp.rb +10 -1
- data/lib/active_support/core_ext/securerandom.rb +45 -0
- data/lib/active_support/core_ext/string/access.rb +42 -51
- data/lib/active_support/core_ext/string/behavior.rb +3 -1
- data/lib/active_support/core_ext/string/conversions.rb +18 -13
- data/lib/active_support/core_ext/string/exclude.rb +5 -3
- data/lib/active_support/core_ext/string/filters.rb +97 -7
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +106 -25
- data/lib/active_support/core_ext/string/inquiry.rb +4 -1
- data/lib/active_support/core_ext/string/multibyte.rb +18 -9
- data/lib/active_support/core_ext/string/output_safety.rb +227 -54
- data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
- data/lib/active_support/core_ext/string/strip.rb +6 -5
- data/lib/active_support/core_ext/string/zones.rb +4 -1
- data/lib/active_support/core_ext/string.rb +15 -13
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/time/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +178 -116
- data/lib/active_support/core_ext/time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/time/conversions.rb +37 -25
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/time/zones.rb +44 -42
- data/lib/active_support/core_ext/time.rb +8 -5
- data/lib/active_support/core_ext/uri.rb +4 -25
- data/lib/active_support/core_ext.rb +4 -2
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +226 -0
- data/lib/active_support/dependencies/autoload.rb +3 -1
- data/lib/active_support/dependencies/interlock.rb +49 -0
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +71 -696
- data/lib/active_support/deprecation/behaviors.rb +65 -16
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +16 -2
- data/lib/active_support/deprecation/method_wrappers.rb +62 -21
- data/lib/active_support/deprecation/proxy_wrappers.rb +82 -31
- data/lib/active_support/deprecation/reporting.rb +81 -18
- data/lib/active_support/deprecation.rb +19 -11
- data/lib/active_support/descendants_tracker.rb +192 -34
- data/lib/active_support/digest.rb +22 -0
- data/lib/active_support/duration/iso8601_parser.rb +123 -0
- data/lib/active_support/duration/iso8601_serializer.rb +67 -0
- data/lib/active_support/duration.rb +437 -39
- data/lib/active_support/encrypted_configuration.rb +56 -0
- data/lib/active_support/encrypted_file.rb +117 -0
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/error_reporter.rb +117 -0
- data/lib/active_support/evented_file_update_checker.rb +170 -0
- data/lib/active_support/execution_context/test_helper.rb +13 -0
- data/lib/active_support/execution_context.rb +53 -0
- data/lib/active_support/execution_wrapper.rb +151 -0
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +62 -37
- data/lib/active_support/fork_tracker.rb +71 -0
- data/lib/active_support/gem_version.rb +17 -0
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +207 -54
- data/lib/active_support/html_safe_translation.rb +43 -0
- data/lib/active_support/i18n.rb +10 -6
- data/lib/active_support/i18n_railtie.rb +48 -19
- data/lib/active_support/inflections.rb +19 -12
- data/lib/active_support/inflector/inflections.rb +97 -37
- data/lib/active_support/inflector/methods.rb +192 -157
- data/lib/active_support/inflector/transliterate.rb +83 -33
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/isolated_execution_state.rb +64 -0
- data/lib/active_support/json/decoding.rb +37 -42
- data/lib/active_support/json/encoding.rb +93 -293
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/key_generator.rb +30 -47
- data/lib/active_support/lazy_load_hooks.rb +54 -21
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +10 -4
- data/lib/active_support/log_subscriber/test_helper.rb +14 -12
- data/lib/active_support/log_subscriber.rb +61 -18
- data/lib/active_support/logger.rb +40 -4
- data/lib/active_support/logger_silence.rb +17 -20
- data/lib/active_support/logger_thread_safe_level.rb +69 -0
- data/lib/active_support/message_encryptor.rb +178 -55
- data/lib/active_support/message_verifier.rb +195 -26
- data/lib/active_support/messages/metadata.rb +80 -0
- data/lib/active_support/messages/rotation_configuration.rb +23 -0
- data/lib/active_support/messages/rotator.rb +57 -0
- data/lib/active_support/multibyte/chars.rb +45 -92
- data/lib/active_support/multibyte/unicode.rb +44 -377
- data/lib/active_support/multibyte.rb +5 -3
- data/lib/active_support/notifications/fanout.rb +177 -44
- data/lib/active_support/notifications/instrumenter.rb +117 -17
- data/lib/active_support/notifications.rb +106 -39
- data/lib/active_support/number_helper/number_converter.rb +181 -0
- data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +30 -0
- data/lib/active_support/number_helper/number_to_human_converter.rb +69 -0
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +60 -0
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
- data/lib/active_support/number_helper/number_to_phone_converter.rb +59 -0
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +59 -0
- data/lib/active_support/number_helper/rounding_helper.rb +46 -0
- data/lib/active_support/number_helper.rb +152 -394
- data/lib/active_support/option_merger.rb +18 -5
- data/lib/active_support/ordered_hash.rb +8 -6
- data/lib/active_support/ordered_options.rb +43 -7
- data/lib/active_support/parameter_filter.rb +138 -0
- data/lib/active_support/per_thread_registry.rb +24 -11
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +10 -11
- data/lib/active_support/railtie.rb +118 -12
- data/lib/active_support/reloader.rb +130 -0
- data/lib/active_support/rescuable.rb +112 -57
- data/lib/active_support/ruby_features.rb +7 -0
- data/lib/active_support/secure_compare_rotator.rb +51 -0
- data/lib/active_support/security_utils.rb +38 -0
- data/lib/active_support/string_inquirer.rb +11 -4
- data/lib/active_support/subscriber.rb +109 -39
- data/lib/active_support/tagged_logging.rb +54 -17
- data/lib/active_support/test_case.rb +121 -37
- data/lib/active_support/testing/assertions.rb +177 -39
- data/lib/active_support/testing/autorun.rb +5 -3
- data/lib/active_support/testing/constant_lookup.rb +3 -6
- data/lib/active_support/testing/declarative.rb +10 -22
- data/lib/active_support/testing/deprecation.rb +65 -11
- data/lib/active_support/testing/file_fixtures.rb +38 -0
- data/lib/active_support/testing/isolation.rb +56 -87
- data/lib/active_support/testing/method_call_assertions.rb +70 -0
- data/lib/active_support/testing/parallelization/server.rb +82 -0
- data/lib/active_support/testing/parallelization/worker.rb +103 -0
- data/lib/active_support/testing/parallelization.rb +55 -0
- data/lib/active_support/testing/parallelize_executor.rb +76 -0
- data/lib/active_support/testing/setup_and_teardown.rb +30 -10
- data/lib/active_support/testing/stream.rb +41 -0
- data/lib/active_support/testing/tagged_logging.rb +6 -4
- data/lib/active_support/testing/time_helpers.rb +246 -0
- data/lib/active_support/time.rb +13 -13
- data/lib/active_support/time_with_zone.rb +315 -90
- data/lib/active_support/values/time_zone.rb +306 -135
- data/lib/active_support/version.rb +6 -7
- data/lib/active_support/xml_mini/jdom.rb +117 -115
- data/lib/active_support/xml_mini/libxml.rb +22 -21
- data/lib/active_support/xml_mini/libxmlsax.rb +17 -19
- data/lib/active_support/xml_mini/nokogiri.rb +19 -19
- data/lib/active_support/xml_mini/nokogirisax.rb +16 -17
- data/lib/active_support/xml_mini/rexml.rb +25 -17
- data/lib/active_support/xml_mini.rb +67 -56
- data/lib/active_support.rb +58 -3
- metadata +125 -66
- data/lib/active_support/basic_object.rb +0 -11
- data/lib/active_support/buffered_logger.rb +0 -21
- data/lib/active_support/concurrency/latch.rb +0 -27
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
- data/lib/active_support/core_ext/array/uniq_by.rb +0 -19
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -40
- data/lib/active_support/core_ext/date_time/zones.rb +0 -24
- data/lib/active_support/core_ext/hash/diff.rb +0 -14
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
- data/lib/active_support/core_ext/logger.rb +0 -67
- data/lib/active_support/core_ext/marshal.rb +0 -21
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
- data/lib/active_support/core_ext/module/reachable.rb +0 -8
- data/lib/active_support/core_ext/object/to_json.rb +0 -27
- data/lib/active_support/core_ext/proc.rb +0 -17
- data/lib/active_support/core_ext/range/include_range.rb +0 -23
- data/lib/active_support/core_ext/string/encoding.rb +0 -8
- data/lib/active_support/core_ext/struct.rb +0 -6
- data/lib/active_support/core_ext/thread.rb +0 -79
- data/lib/active_support/core_ext/time/marshal.rb +0 -30
- data/lib/active_support/file_watcher.rb +0 -36
- data/lib/active_support/json/variable.rb +0 -18
- data/lib/active_support/testing/pending.rb +0 -14
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,25 +1,9 @@
|
|
1
|
-
|
2
|
-
REGEXPS = [
|
3
|
-
/^no such file to load -- (.+)$/i,
|
4
|
-
/^Missing \w+ (?:file\s*)?([^\s]+.rb)$/i,
|
5
|
-
/^Missing API definition file in (.+)$/i,
|
6
|
-
/^cannot load such file -- (.+)$/i,
|
7
|
-
]
|
8
|
-
|
9
|
-
unless method_defined?(:path)
|
10
|
-
def path
|
11
|
-
@path ||= begin
|
12
|
-
REGEXPS.find do |regex|
|
13
|
-
message =~ regex
|
14
|
-
end
|
15
|
-
$1
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
1
|
+
# frozen_string_literal: true
|
19
2
|
|
3
|
+
class LoadError
|
4
|
+
# Returns true if the given path name (except perhaps for the ".rb"
|
5
|
+
# extension) is the missing file which caused the exception to be raised.
|
20
6
|
def is_missing?(location)
|
21
|
-
location.
|
7
|
+
location.delete_suffix(".rb") == path.to_s.delete_suffix(".rb")
|
22
8
|
end
|
23
9
|
end
|
24
|
-
|
25
|
-
MissingSourceFile = LoadError
|
@@ -1,49 +1,8 @@
|
|
1
|
-
|
2
|
-
# Encapsulates the common pattern of:
|
3
|
-
#
|
4
|
-
# alias_method :foo_without_feature, :foo
|
5
|
-
# alias_method :foo, :foo_with_feature
|
6
|
-
#
|
7
|
-
# With this, you simply do:
|
8
|
-
#
|
9
|
-
# alias_method_chain :foo, :feature
|
10
|
-
#
|
11
|
-
# And both aliases are set up for you.
|
12
|
-
#
|
13
|
-
# Query and bang methods (foo?, foo!) keep the same punctuation:
|
14
|
-
#
|
15
|
-
# alias_method_chain :foo?, :feature
|
16
|
-
#
|
17
|
-
# is equivalent to
|
18
|
-
#
|
19
|
-
# alias_method :foo_without_feature?, :foo?
|
20
|
-
# alias_method :foo?, :foo_with_feature?
|
21
|
-
#
|
22
|
-
# so you can safely chain foo, foo?, and foo! with the same feature.
|
23
|
-
def alias_method_chain(target, feature)
|
24
|
-
# Strip out punctuation on predicates or bang methods since
|
25
|
-
# e.g. target?_without_feature is not a valid method name.
|
26
|
-
aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
|
27
|
-
yield(aliased_target, punctuation) if block_given?
|
28
|
-
|
29
|
-
with_method = "#{aliased_target}_with_#{feature}#{punctuation}"
|
30
|
-
without_method = "#{aliased_target}_without_#{feature}#{punctuation}"
|
31
|
-
|
32
|
-
alias_method without_method, target
|
33
|
-
alias_method target, with_method
|
34
|
-
|
35
|
-
case
|
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
|
42
|
-
end
|
43
|
-
end
|
1
|
+
# frozen_string_literal: true
|
44
2
|
|
3
|
+
class Module
|
45
4
|
# Allows you to make aliases for attributes, which includes
|
46
|
-
# getter, setter, and
|
5
|
+
# getter, setter, and a predicate.
|
47
6
|
#
|
48
7
|
# class Content < ActiveRecord::Base
|
49
8
|
# # has a title attribute
|
@@ -60,6 +19,9 @@ class Module
|
|
60
19
|
# e.subject = "Megastars"
|
61
20
|
# e.title # => "Megastars"
|
62
21
|
def alias_attribute(new_name, old_name)
|
22
|
+
# The following reader methods use an explicit `self` receiver in order to
|
23
|
+
# support aliases that start with an uppercase letter. Otherwise, they would
|
24
|
+
# be resolved as constants instead.
|
63
25
|
module_eval <<-STR, __FILE__, __LINE__ + 1
|
64
26
|
def #{new_name}; self.#{old_name}; end # def subject; self.title; end
|
65
27
|
def #{new_name}?; self.#{old_name}?; end # def subject?; self.title?; end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Module
|
2
4
|
# A module may or may not have a name.
|
3
5
|
#
|
@@ -7,12 +9,21 @@ class Module
|
|
7
9
|
# m = Module.new
|
8
10
|
# m.name # => nil
|
9
11
|
#
|
12
|
+
# +anonymous?+ method returns true if module does not have a name, false otherwise:
|
13
|
+
#
|
14
|
+
# Module.new.anonymous? # => true
|
15
|
+
#
|
16
|
+
# module M; end
|
17
|
+
# M.anonymous? # => false
|
18
|
+
#
|
10
19
|
# A module gets a name when it is first assigned to a constant. Either
|
11
20
|
# via the +module+ or +class+ keyword or by an explicit assignment:
|
12
21
|
#
|
13
22
|
# m = Module.new # creates an anonymous module
|
14
|
-
#
|
23
|
+
# m.anonymous? # => true
|
24
|
+
# M = m # m gets a name here as a side-effect
|
15
25
|
# m.name # => "M"
|
26
|
+
# m.anonymous? # => false
|
16
27
|
def anonymous?
|
17
28
|
name.nil?
|
18
29
|
end
|
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Module
|
2
4
|
# Declares an attribute reader backed by an internally-named instance variable.
|
3
5
|
def attr_internal_reader(*attrs)
|
4
|
-
attrs.each {|attr_name| attr_internal_define(attr_name, :reader)}
|
6
|
+
attrs.each { |attr_name| attr_internal_define(attr_name, :reader) }
|
5
7
|
end
|
6
8
|
|
7
9
|
# Declares an attribute writer backed by an internally-named instance variable.
|
8
10
|
def attr_internal_writer(*attrs)
|
9
|
-
attrs.each {|attr_name| attr_internal_define(attr_name, :writer)}
|
11
|
+
attrs.each { |attr_name| attr_internal_define(attr_name, :writer) }
|
10
12
|
end
|
11
13
|
|
12
14
|
# Declares an attribute reader and writer backed by an internally-named instance
|
@@ -18,7 +20,7 @@ class Module
|
|
18
20
|
alias_method :attr_internal, :attr_internal_accessor
|
19
21
|
|
20
22
|
class << self; attr_accessor :attr_internal_naming_format end
|
21
|
-
self.attr_internal_naming_format =
|
23
|
+
self.attr_internal_naming_format = "@_%s"
|
22
24
|
|
23
25
|
private
|
24
26
|
def attr_internal_ivar_name(attr)
|
@@ -26,11 +28,9 @@ class Module
|
|
26
28
|
end
|
27
29
|
|
28
30
|
def attr_internal_define(attr_name, type)
|
29
|
-
internal_name = attr_internal_ivar_name(attr_name).
|
30
|
-
|
31
|
-
|
32
|
-
send("attr_#{type}", internal_name)
|
33
|
-
end
|
31
|
+
internal_name = attr_internal_ivar_name(attr_name).delete_prefix("@")
|
32
|
+
# use native attr_* methods as they are faster on some Ruby implementations
|
33
|
+
public_send("attr_#{type}", internal_name)
|
34
34
|
attr_name, internal_name = "#{attr_name}=", "#{internal_name}=" if type == :writer
|
35
35
|
alias_method attr_name, internal_name
|
36
36
|
remove_method internal_name
|
@@ -1,66 +1,208 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# == Attribute Accessors
|
4
|
+
#
|
5
|
+
# Extends the module object with class/module and instance accessors for
|
6
|
+
# class/module attributes, just like the native attr* accessors for instance
|
7
|
+
# attributes.
|
3
8
|
class Module
|
4
|
-
|
5
|
-
|
9
|
+
# Defines a class attribute and creates a class and instance reader methods.
|
10
|
+
# The underlying class variable is set to +nil+, if it is not previously
|
11
|
+
# defined. All class and instance methods created will be public, even if
|
12
|
+
# this method is called with a private or protected access modifier.
|
13
|
+
#
|
14
|
+
# module HairColors
|
15
|
+
# mattr_reader :hair_colors
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# HairColors.hair_colors # => nil
|
19
|
+
# HairColors.class_variable_set("@@hair_colors", [:brown, :black])
|
20
|
+
# HairColors.hair_colors # => [:brown, :black]
|
21
|
+
#
|
22
|
+
# The attribute name must be a valid method name in Ruby.
|
23
|
+
#
|
24
|
+
# module Foo
|
25
|
+
# mattr_reader :"1_Badname"
|
26
|
+
# end
|
27
|
+
# # => NameError: invalid attribute name: 1_Badname
|
28
|
+
#
|
29
|
+
# To omit the instance reader method, pass
|
30
|
+
# <tt>instance_reader: false</tt> or <tt>instance_accessor: false</tt>.
|
31
|
+
#
|
32
|
+
# module HairColors
|
33
|
+
# mattr_reader :hair_colors, instance_reader: false
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# class Person
|
37
|
+
# include HairColors
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# Person.new.hair_colors # => NoMethodError
|
41
|
+
#
|
42
|
+
# You can set a default value for the attribute.
|
43
|
+
#
|
44
|
+
# module HairColors
|
45
|
+
# mattr_reader :hair_colors, default: [:brown, :black, :blonde, :red]
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# class Person
|
49
|
+
# include HairColors
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# Person.new.hair_colors # => [:brown, :black, :blonde, :red]
|
53
|
+
def mattr_reader(*syms, instance_reader: true, instance_accessor: true, default: nil, location: nil)
|
54
|
+
raise TypeError, "module attributes should be defined directly on class, not singleton" if singleton_class?
|
55
|
+
location ||= caller_locations(1, 1).first
|
56
|
+
|
57
|
+
definition = []
|
6
58
|
syms.each do |sym|
|
7
|
-
raise NameError.new(
|
8
|
-
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
9
|
-
@@#{sym} = nil unless defined? @@#{sym}
|
59
|
+
raise NameError.new("invalid attribute name: #{sym}") unless /\A[_A-Za-z]\w*\z/.match?(sym)
|
10
60
|
|
11
|
-
|
12
|
-
@@#{sym}
|
13
|
-
end
|
14
|
-
EOS
|
61
|
+
definition << "def self.#{sym}; @@#{sym}; end"
|
15
62
|
|
16
|
-
|
17
|
-
|
18
|
-
def #{sym}
|
19
|
-
@@#{sym}
|
20
|
-
end
|
21
|
-
EOS
|
63
|
+
if instance_reader && instance_accessor
|
64
|
+
definition << "def #{sym}; @@#{sym}; end"
|
22
65
|
end
|
66
|
+
|
67
|
+
sym_default_value = (block_given? && default.nil?) ? yield : default
|
68
|
+
class_variable_set("@@#{sym}", sym_default_value) unless sym_default_value.nil? && class_variable_defined?("@@#{sym}")
|
23
69
|
end
|
70
|
+
|
71
|
+
module_eval(definition.join(";"), location.path, location.lineno)
|
24
72
|
end
|
73
|
+
alias :cattr_reader :mattr_reader
|
25
74
|
|
26
|
-
|
27
|
-
|
75
|
+
# Defines a class attribute and creates a class and instance writer methods to
|
76
|
+
# allow assignment to the attribute. All class and instance methods created
|
77
|
+
# will be public, even if this method is called with a private or protected
|
78
|
+
# access modifier.
|
79
|
+
#
|
80
|
+
# module HairColors
|
81
|
+
# mattr_writer :hair_colors
|
82
|
+
# end
|
83
|
+
#
|
84
|
+
# class Person
|
85
|
+
# include HairColors
|
86
|
+
# end
|
87
|
+
#
|
88
|
+
# HairColors.hair_colors = [:brown, :black]
|
89
|
+
# Person.class_variable_get("@@hair_colors") # => [:brown, :black]
|
90
|
+
# Person.new.hair_colors = [:blonde, :red]
|
91
|
+
# HairColors.class_variable_get("@@hair_colors") # => [:blonde, :red]
|
92
|
+
#
|
93
|
+
# To omit the instance writer method, pass
|
94
|
+
# <tt>instance_writer: false</tt> or <tt>instance_accessor: false</tt>.
|
95
|
+
#
|
96
|
+
# module HairColors
|
97
|
+
# mattr_writer :hair_colors, instance_writer: false
|
98
|
+
# end
|
99
|
+
#
|
100
|
+
# class Person
|
101
|
+
# include HairColors
|
102
|
+
# end
|
103
|
+
#
|
104
|
+
# Person.new.hair_colors = [:blonde, :red] # => NoMethodError
|
105
|
+
#
|
106
|
+
# You can set a default value for the attribute.
|
107
|
+
#
|
108
|
+
# module HairColors
|
109
|
+
# mattr_writer :hair_colors, default: [:brown, :black, :blonde, :red]
|
110
|
+
# end
|
111
|
+
#
|
112
|
+
# class Person
|
113
|
+
# include HairColors
|
114
|
+
# end
|
115
|
+
#
|
116
|
+
# Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red]
|
117
|
+
def mattr_writer(*syms, instance_writer: true, instance_accessor: true, default: nil, location: nil)
|
118
|
+
raise TypeError, "module attributes should be defined directly on class, not singleton" if singleton_class?
|
119
|
+
location ||= caller_locations(1, 1).first
|
120
|
+
|
121
|
+
definition = []
|
28
122
|
syms.each do |sym|
|
29
|
-
raise NameError.new(
|
30
|
-
|
31
|
-
def self.#{sym}=(obj)
|
32
|
-
@@#{sym} = obj
|
33
|
-
end
|
34
|
-
EOS
|
123
|
+
raise NameError.new("invalid attribute name: #{sym}") unless /\A[_A-Za-z]\w*\z/.match?(sym)
|
124
|
+
definition << "def self.#{sym}=(val); @@#{sym} = val; end"
|
35
125
|
|
36
|
-
|
37
|
-
|
38
|
-
def #{sym}=(obj)
|
39
|
-
@@#{sym} = obj
|
40
|
-
end
|
41
|
-
EOS
|
126
|
+
if instance_writer && instance_accessor
|
127
|
+
definition << "def #{sym}=(val); @@#{sym} = val; end"
|
42
128
|
end
|
129
|
+
|
130
|
+
sym_default_value = (block_given? && default.nil?) ? yield : default
|
131
|
+
class_variable_set("@@#{sym}", sym_default_value) unless sym_default_value.nil? && class_variable_defined?("@@#{sym}")
|
43
132
|
end
|
133
|
+
|
134
|
+
module_eval(definition.join(";"), location.path, location.lineno)
|
44
135
|
end
|
136
|
+
alias :cattr_writer :mattr_writer
|
45
137
|
|
46
|
-
#
|
47
|
-
#
|
138
|
+
# Defines both class and instance accessors for class attributes.
|
139
|
+
# All class and instance methods created will be public, even if
|
140
|
+
# this method is called with a private or protected access modifier.
|
141
|
+
#
|
142
|
+
# module HairColors
|
143
|
+
# mattr_accessor :hair_colors
|
144
|
+
# end
|
145
|
+
#
|
146
|
+
# class Person
|
147
|
+
# include HairColors
|
148
|
+
# end
|
149
|
+
#
|
150
|
+
# HairColors.hair_colors = [:brown, :black, :blonde, :red]
|
151
|
+
# HairColors.hair_colors # => [:brown, :black, :blonde, :red]
|
152
|
+
# Person.new.hair_colors # => [:brown, :black, :blonde, :red]
|
48
153
|
#
|
49
|
-
#
|
50
|
-
#
|
154
|
+
# If a subclass changes the value then that would also change the value for
|
155
|
+
# parent class. Similarly if parent class changes the value then that would
|
156
|
+
# change the value of subclasses too.
|
51
157
|
#
|
52
|
-
#
|
158
|
+
# class Citizen < Person
|
53
159
|
# end
|
54
160
|
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
161
|
+
# Citizen.new.hair_colors << :blue
|
162
|
+
# Person.new.hair_colors # => [:brown, :black, :blonde, :red, :blue]
|
163
|
+
#
|
164
|
+
# To omit the instance writer method, pass <tt>instance_writer: false</tt>.
|
165
|
+
# To omit the instance reader method, pass <tt>instance_reader: false</tt>.
|
166
|
+
#
|
167
|
+
# module HairColors
|
168
|
+
# mattr_accessor :hair_colors, instance_writer: false, instance_reader: false
|
169
|
+
# end
|
170
|
+
#
|
171
|
+
# class Person
|
172
|
+
# include HairColors
|
173
|
+
# end
|
174
|
+
#
|
175
|
+
# Person.new.hair_colors = [:brown] # => NoMethodError
|
176
|
+
# Person.new.hair_colors # => NoMethodError
|
177
|
+
#
|
178
|
+
# Or pass <tt>instance_accessor: false</tt>, to omit both instance methods.
|
179
|
+
#
|
180
|
+
# module HairColors
|
181
|
+
# mattr_accessor :hair_colors, instance_accessor: false
|
182
|
+
# end
|
183
|
+
#
|
184
|
+
# class Person
|
185
|
+
# include HairColors
|
186
|
+
# end
|
187
|
+
#
|
188
|
+
# Person.new.hair_colors = [:brown] # => NoMethodError
|
189
|
+
# Person.new.hair_colors # => NoMethodError
|
190
|
+
#
|
191
|
+
# You can set a default value for the attribute.
|
192
|
+
#
|
193
|
+
# module HairColors
|
194
|
+
# mattr_accessor :hair_colors, default: [:brown, :black, :blonde, :red]
|
195
|
+
# end
|
196
|
+
#
|
197
|
+
# class Person
|
198
|
+
# include HairColors
|
199
|
+
# end
|
58
200
|
#
|
59
|
-
#
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
mattr_writer(*syms)
|
201
|
+
# Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red]
|
202
|
+
def mattr_accessor(*syms, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil, &blk)
|
203
|
+
location = caller_locations(1, 1).first
|
204
|
+
mattr_reader(*syms, instance_reader: instance_reader, instance_accessor: instance_accessor, default: default, location: location, &blk)
|
205
|
+
mattr_writer(*syms, instance_writer: instance_writer, instance_accessor: instance_accessor, default: default, location: location)
|
65
206
|
end
|
207
|
+
alias :cattr_accessor :mattr_accessor
|
66
208
|
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# == Attribute Accessors per Thread
|
4
|
+
#
|
5
|
+
# Extends the module object with class/module and instance accessors for
|
6
|
+
# class/module attributes, just like the native attr* accessors for instance
|
7
|
+
# attributes, but does so on a per-thread basis.
|
8
|
+
#
|
9
|
+
# So the values are scoped within the Thread.current space under the class name
|
10
|
+
# of the module.
|
11
|
+
#
|
12
|
+
# Note that it can also be scoped per-fiber if Rails.application.config.active_support.isolation_level
|
13
|
+
# is set to `:fiber`
|
14
|
+
class Module
|
15
|
+
# Defines a per-thread class attribute and creates class and instance reader methods.
|
16
|
+
# The underlying per-thread class variable is set to +nil+, if it is not previously defined.
|
17
|
+
#
|
18
|
+
# module Current
|
19
|
+
# thread_mattr_reader :user
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# Current.user = "DHH"
|
23
|
+
# Current.user # => "DHH"
|
24
|
+
# Thread.new { Current.user }.values # => nil
|
25
|
+
#
|
26
|
+
# The attribute name must be a valid method name in Ruby.
|
27
|
+
#
|
28
|
+
# module Foo
|
29
|
+
# thread_mattr_reader :"1_Badname"
|
30
|
+
# end
|
31
|
+
# # => NameError: invalid attribute name: 1_Badname
|
32
|
+
#
|
33
|
+
# To omit the instance reader method, pass
|
34
|
+
# <tt>instance_reader: false</tt> or <tt>instance_accessor: false</tt>.
|
35
|
+
#
|
36
|
+
# class Current
|
37
|
+
# thread_mattr_reader :user, instance_reader: false
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# Current.new.user # => NoMethodError
|
41
|
+
def thread_mattr_reader(*syms, instance_reader: true, instance_accessor: true, default: nil) # :nodoc:
|
42
|
+
syms.each do |sym|
|
43
|
+
raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym)
|
44
|
+
|
45
|
+
# The following generated method concatenates `name` because we want it
|
46
|
+
# to work with inheritance via polymorphism.
|
47
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
48
|
+
def self.#{sym}
|
49
|
+
@__thread_mattr_#{sym} ||= "attr_\#{name}_#{sym}"
|
50
|
+
::ActiveSupport::IsolatedExecutionState[@__thread_mattr_#{sym}]
|
51
|
+
end
|
52
|
+
EOS
|
53
|
+
|
54
|
+
if instance_reader && instance_accessor
|
55
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
56
|
+
def #{sym}
|
57
|
+
self.class.#{sym}
|
58
|
+
end
|
59
|
+
EOS
|
60
|
+
end
|
61
|
+
|
62
|
+
::ActiveSupport::IsolatedExecutionState["attr_#{name}_#{sym}"] = default unless default.nil?
|
63
|
+
end
|
64
|
+
end
|
65
|
+
alias :thread_cattr_reader :thread_mattr_reader
|
66
|
+
|
67
|
+
# Defines a per-thread class attribute and creates a class and instance writer methods to
|
68
|
+
# allow assignment to the attribute.
|
69
|
+
#
|
70
|
+
# module Current
|
71
|
+
# thread_mattr_writer :user
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
# Current.user = "DHH"
|
75
|
+
# Thread.current[:attr_Current_user] # => "DHH"
|
76
|
+
#
|
77
|
+
# To omit the instance writer method, pass
|
78
|
+
# <tt>instance_writer: false</tt> or <tt>instance_accessor: false</tt>.
|
79
|
+
#
|
80
|
+
# class Current
|
81
|
+
# thread_mattr_writer :user, instance_writer: false
|
82
|
+
# end
|
83
|
+
#
|
84
|
+
# Current.new.user = "DHH" # => NoMethodError
|
85
|
+
def thread_mattr_writer(*syms, instance_writer: true, instance_accessor: true, default: nil) # :nodoc:
|
86
|
+
syms.each do |sym|
|
87
|
+
raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym)
|
88
|
+
|
89
|
+
# The following generated method concatenates `name` because we want it
|
90
|
+
# to work with inheritance via polymorphism.
|
91
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
92
|
+
def self.#{sym}=(obj)
|
93
|
+
@__thread_mattr_#{sym} ||= "attr_\#{name}_#{sym}"
|
94
|
+
::ActiveSupport::IsolatedExecutionState[@__thread_mattr_#{sym}] = obj
|
95
|
+
end
|
96
|
+
EOS
|
97
|
+
|
98
|
+
if instance_writer && instance_accessor
|
99
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
100
|
+
def #{sym}=(obj)
|
101
|
+
self.class.#{sym} = obj
|
102
|
+
end
|
103
|
+
EOS
|
104
|
+
end
|
105
|
+
|
106
|
+
public_send("#{sym}=", default) unless default.nil?
|
107
|
+
end
|
108
|
+
end
|
109
|
+
alias :thread_cattr_writer :thread_mattr_writer
|
110
|
+
|
111
|
+
# Defines both class and instance accessors for class attributes.
|
112
|
+
#
|
113
|
+
# class Account
|
114
|
+
# thread_mattr_accessor :user
|
115
|
+
# end
|
116
|
+
#
|
117
|
+
# Account.user = "DHH"
|
118
|
+
# Account.user # => "DHH"
|
119
|
+
# Account.new.user # => "DHH"
|
120
|
+
#
|
121
|
+
# Unlike `mattr_accessor`, values are *not* shared with subclasses or parent classes.
|
122
|
+
# If a subclass changes the value, the parent class' value is not changed.
|
123
|
+
# If the parent class changes the value, the value of subclasses is not changed.
|
124
|
+
#
|
125
|
+
# class Customer < Account
|
126
|
+
# end
|
127
|
+
#
|
128
|
+
# Account.user # => "DHH"
|
129
|
+
# Customer.user # => nil
|
130
|
+
# Customer.user = "Rafael"
|
131
|
+
# Customer.user # => "Rafael"
|
132
|
+
# Account.user # => "DHH"
|
133
|
+
#
|
134
|
+
# To omit the instance writer method, pass <tt>instance_writer: false</tt>.
|
135
|
+
# To omit the instance reader method, pass <tt>instance_reader: false</tt>.
|
136
|
+
#
|
137
|
+
# class Current
|
138
|
+
# thread_mattr_accessor :user, instance_writer: false, instance_reader: false
|
139
|
+
# end
|
140
|
+
#
|
141
|
+
# Current.new.user = "DHH" # => NoMethodError
|
142
|
+
# Current.new.user # => NoMethodError
|
143
|
+
#
|
144
|
+
# Or pass <tt>instance_accessor: false</tt>, to omit both instance methods.
|
145
|
+
#
|
146
|
+
# class Current
|
147
|
+
# thread_mattr_accessor :user, instance_accessor: false
|
148
|
+
# end
|
149
|
+
#
|
150
|
+
# Current.new.user = "DHH" # => NoMethodError
|
151
|
+
# Current.new.user # => NoMethodError
|
152
|
+
def thread_mattr_accessor(*syms, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil)
|
153
|
+
thread_mattr_reader(*syms, instance_reader: instance_reader, instance_accessor: instance_accessor, default: default)
|
154
|
+
thread_mattr_writer(*syms, instance_writer: instance_writer, instance_accessor: instance_accessor)
|
155
|
+
end
|
156
|
+
alias :thread_cattr_accessor :thread_mattr_accessor
|
157
|
+
end
|