activesupport 5.0.7.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/CHANGELOG.md +1013 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +39 -0
- data/lib/active_support.rb +99 -0
- data/lib/active_support/all.rb +3 -0
- data/lib/active_support/array_inquirer.rb +44 -0
- data/lib/active_support/backtrace_cleaner.rb +103 -0
- data/lib/active_support/benchmarkable.rb +49 -0
- data/lib/active_support/builder.rb +6 -0
- data/lib/active_support/cache.rb +701 -0
- data/lib/active_support/cache/file_store.rb +204 -0
- data/lib/active_support/cache/mem_cache_store.rb +207 -0
- data/lib/active_support/cache/memory_store.rb +167 -0
- data/lib/active_support/cache/null_store.rb +41 -0
- data/lib/active_support/cache/strategy/local_cache.rb +172 -0
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +44 -0
- data/lib/active_support/callbacks.rb +791 -0
- data/lib/active_support/concern.rb +142 -0
- data/lib/active_support/concurrency/latch.rb +26 -0
- data/lib/active_support/concurrency/share_lock.rb +226 -0
- data/lib/active_support/configurable.rb +148 -0
- data/lib/active_support/core_ext.rb +4 -0
- data/lib/active_support/core_ext/array.rb +7 -0
- data/lib/active_support/core_ext/array/access.rb +90 -0
- data/lib/active_support/core_ext/array/conversions.rb +211 -0
- data/lib/active_support/core_ext/array/extract_options.rb +29 -0
- data/lib/active_support/core_ext/array/grouping.rb +107 -0
- data/lib/active_support/core_ext/array/inquiry.rb +17 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +7 -0
- data/lib/active_support/core_ext/array/wrap.rb +46 -0
- data/lib/active_support/core_ext/benchmark.rb +14 -0
- data/lib/active_support/core_ext/big_decimal.rb +1 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
- data/lib/active_support/core_ext/class.rb +2 -0
- data/lib/active_support/core_ext/class/attribute.rb +128 -0
- data/lib/active_support/core_ext/class/attribute_accessors.rb +4 -0
- data/lib/active_support/core_ext/class/subclasses.rb +41 -0
- data/lib/active_support/core_ext/date.rb +5 -0
- data/lib/active_support/core_ext/date/acts_like.rb +8 -0
- data/lib/active_support/core_ext/date/blank.rb +12 -0
- data/lib/active_support/core_ext/date/calculations.rb +143 -0
- data/lib/active_support/core_ext/date/conversions.rb +95 -0
- data/lib/active_support/core_ext/date/zones.rb +6 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +335 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +14 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
- data/lib/active_support/core_ext/date_time.rb +5 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +14 -0
- data/lib/active_support/core_ext/date_time/blank.rb +12 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +199 -0
- data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +105 -0
- data/lib/active_support/core_ext/digest/uuid.rb +51 -0
- data/lib/active_support/core_ext/enumerable.rb +146 -0
- data/lib/active_support/core_ext/file.rb +1 -0
- data/lib/active_support/core_ext/file/atomic.rb +68 -0
- data/lib/active_support/core_ext/hash.rb +9 -0
- data/lib/active_support/core_ext/hash/compact.rb +24 -0
- data/lib/active_support/core_ext/hash/conversions.rb +262 -0
- data/lib/active_support/core_ext/hash/deep_merge.rb +38 -0
- data/lib/active_support/core_ext/hash/except.rb +22 -0
- data/lib/active_support/core_ext/hash/indifferent_access.rb +23 -0
- data/lib/active_support/core_ext/hash/keys.rb +170 -0
- data/lib/active_support/core_ext/hash/reverse_merge.rb +22 -0
- data/lib/active_support/core_ext/hash/slice.rb +48 -0
- data/lib/active_support/core_ext/hash/transform_values.rb +29 -0
- data/lib/active_support/core_ext/integer.rb +3 -0
- data/lib/active_support/core_ext/integer/inflections.rb +29 -0
- data/lib/active_support/core_ext/integer/multiple.rb +10 -0
- data/lib/active_support/core_ext/integer/time.rb +29 -0
- data/lib/active_support/core_ext/kernel.rb +4 -0
- data/lib/active_support/core_ext/kernel/agnostics.rb +11 -0
- data/lib/active_support/core_ext/kernel/concern.rb +12 -0
- data/lib/active_support/core_ext/kernel/debugger.rb +3 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +43 -0
- data/lib/active_support/core_ext/kernel/singleton_class.rb +6 -0
- data/lib/active_support/core_ext/load_error.rb +31 -0
- data/lib/active_support/core_ext/marshal.rb +22 -0
- data/lib/active_support/core_ext/module.rb +12 -0
- data/lib/active_support/core_ext/module/aliasing.rb +74 -0
- data/lib/active_support/core_ext/module/anonymous.rb +28 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +36 -0
- data/lib/active_support/core_ext/module/attribute_accessors.rb +212 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
- data/lib/active_support/core_ext/module/concerning.rb +135 -0
- data/lib/active_support/core_ext/module/delegation.rb +216 -0
- data/lib/active_support/core_ext/module/deprecation.rb +23 -0
- data/lib/active_support/core_ext/module/introspection.rb +68 -0
- data/lib/active_support/core_ext/module/method_transplanting.rb +3 -0
- data/lib/active_support/core_ext/module/qualified_const.rb +70 -0
- data/lib/active_support/core_ext/module/reachable.rb +8 -0
- data/lib/active_support/core_ext/module/remove_method.rb +35 -0
- data/lib/active_support/core_ext/name_error.rb +31 -0
- data/lib/active_support/core_ext/numeric.rb +4 -0
- data/lib/active_support/core_ext/numeric/bytes.rb +64 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +144 -0
- data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
- data/lib/active_support/core_ext/numeric/time.rb +74 -0
- data/lib/active_support/core_ext/object.rb +14 -0
- data/lib/active_support/core_ext/object/acts_like.rb +10 -0
- data/lib/active_support/core_ext/object/blank.rb +143 -0
- data/lib/active_support/core_ext/object/conversions.rb +4 -0
- data/lib/active_support/core_ext/object/deep_dup.rb +53 -0
- data/lib/active_support/core_ext/object/duplicable.rb +124 -0
- data/lib/active_support/core_ext/object/inclusion.rb +27 -0
- data/lib/active_support/core_ext/object/instance_variables.rb +28 -0
- data/lib/active_support/core_ext/object/json.rb +205 -0
- data/lib/active_support/core_ext/object/to_param.rb +1 -0
- data/lib/active_support/core_ext/object/to_query.rb +84 -0
- data/lib/active_support/core_ext/object/try.rb +146 -0
- data/lib/active_support/core_ext/object/with_options.rb +69 -0
- data/lib/active_support/core_ext/range.rb +4 -0
- data/lib/active_support/core_ext/range/conversions.rb +31 -0
- data/lib/active_support/core_ext/range/each.rb +21 -0
- data/lib/active_support/core_ext/range/include_range.rb +23 -0
- data/lib/active_support/core_ext/range/overlaps.rb +8 -0
- data/lib/active_support/core_ext/regexp.rb +5 -0
- data/lib/active_support/core_ext/securerandom.rb +23 -0
- data/lib/active_support/core_ext/string.rb +13 -0
- data/lib/active_support/core_ext/string/access.rb +104 -0
- data/lib/active_support/core_ext/string/behavior.rb +6 -0
- data/lib/active_support/core_ext/string/conversions.rb +57 -0
- data/lib/active_support/core_ext/string/exclude.rb +11 -0
- data/lib/active_support/core_ext/string/filters.rb +102 -0
- data/lib/active_support/core_ext/string/indent.rb +43 -0
- data/lib/active_support/core_ext/string/inflections.rb +244 -0
- data/lib/active_support/core_ext/string/inquiry.rb +13 -0
- data/lib/active_support/core_ext/string/multibyte.rb +53 -0
- data/lib/active_support/core_ext/string/output_safety.rb +260 -0
- data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -0
- data/lib/active_support/core_ext/string/strip.rb +23 -0
- data/lib/active_support/core_ext/string/zones.rb +14 -0
- data/lib/active_support/core_ext/struct.rb +3 -0
- data/lib/active_support/core_ext/time.rb +5 -0
- data/lib/active_support/core_ext/time/acts_like.rb +8 -0
- data/lib/active_support/core_ext/time/calculations.rb +290 -0
- data/lib/active_support/core_ext/time/compatibility.rb +14 -0
- data/lib/active_support/core_ext/time/conversions.rb +67 -0
- data/lib/active_support/core_ext/time/marshal.rb +3 -0
- data/lib/active_support/core_ext/time/zones.rb +111 -0
- data/lib/active_support/core_ext/uri.rb +24 -0
- data/lib/active_support/dependencies.rb +755 -0
- data/lib/active_support/dependencies/autoload.rb +77 -0
- data/lib/active_support/dependencies/interlock.rb +55 -0
- data/lib/active_support/deprecation.rb +43 -0
- data/lib/active_support/deprecation/behaviors.rb +90 -0
- data/lib/active_support/deprecation/instance_delegator.rb +37 -0
- data/lib/active_support/deprecation/method_wrappers.rb +70 -0
- data/lib/active_support/deprecation/proxy_wrappers.rb +149 -0
- data/lib/active_support/deprecation/reporting.rb +112 -0
- data/lib/active_support/descendants_tracker.rb +60 -0
- data/lib/active_support/duration.rb +235 -0
- data/lib/active_support/duration/iso8601_parser.rb +122 -0
- data/lib/active_support/duration/iso8601_serializer.rb +51 -0
- data/lib/active_support/evented_file_update_checker.rb +199 -0
- data/lib/active_support/execution_wrapper.rb +126 -0
- data/lib/active_support/executor.rb +6 -0
- data/lib/active_support/file_update_checker.rb +157 -0
- data/lib/active_support/gem_version.rb +15 -0
- data/lib/active_support/gzip.rb +36 -0
- data/lib/active_support/hash_with_indifferent_access.rb +329 -0
- data/lib/active_support/i18n.rb +13 -0
- data/lib/active_support/i18n_railtie.rb +115 -0
- data/lib/active_support/inflections.rb +70 -0
- data/lib/active_support/inflector.rb +7 -0
- data/lib/active_support/inflector/inflections.rb +242 -0
- data/lib/active_support/inflector/methods.rb +390 -0
- data/lib/active_support/inflector/transliterate.rb +112 -0
- data/lib/active_support/json.rb +2 -0
- data/lib/active_support/json/decoding.rb +74 -0
- data/lib/active_support/json/encoding.rb +127 -0
- data/lib/active_support/key_generator.rb +71 -0
- data/lib/active_support/lazy_load_hooks.rb +76 -0
- data/lib/active_support/locale/en.yml +135 -0
- data/lib/active_support/log_subscriber.rb +109 -0
- data/lib/active_support/log_subscriber/test_helper.rb +104 -0
- data/lib/active_support/logger.rb +106 -0
- data/lib/active_support/logger_silence.rb +28 -0
- data/lib/active_support/logger_thread_safe_level.rb +31 -0
- data/lib/active_support/message_encryptor.rb +114 -0
- data/lib/active_support/message_verifier.rb +134 -0
- data/lib/active_support/multibyte.rb +21 -0
- data/lib/active_support/multibyte/chars.rb +231 -0
- data/lib/active_support/multibyte/unicode.rb +413 -0
- data/lib/active_support/notifications.rb +212 -0
- data/lib/active_support/notifications/fanout.rb +157 -0
- data/lib/active_support/notifications/instrumenter.rb +91 -0
- data/lib/active_support/number_helper.rb +368 -0
- data/lib/active_support/number_helper/number_converter.rb +182 -0
- data/lib/active_support/number_helper/number_to_currency_converter.rb +44 -0
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +28 -0
- data/lib/active_support/number_helper/number_to_human_converter.rb +68 -0
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +62 -0
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +12 -0
- data/lib/active_support/number_helper/number_to_phone_converter.rb +58 -0
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +92 -0
- data/lib/active_support/option_merger.rb +25 -0
- data/lib/active_support/ordered_hash.rb +48 -0
- data/lib/active_support/ordered_options.rb +81 -0
- data/lib/active_support/per_thread_registry.rb +58 -0
- data/lib/active_support/proxy_object.rb +13 -0
- data/lib/active_support/rails.rb +27 -0
- data/lib/active_support/railtie.rb +51 -0
- data/lib/active_support/reloader.rb +129 -0
- data/lib/active_support/rescuable.rb +173 -0
- data/lib/active_support/security_utils.rb +27 -0
- data/lib/active_support/string_inquirer.rb +26 -0
- data/lib/active_support/subscriber.rb +120 -0
- data/lib/active_support/tagged_logging.rb +77 -0
- data/lib/active_support/test_case.rb +88 -0
- data/lib/active_support/testing/assertions.rb +99 -0
- data/lib/active_support/testing/autorun.rb +5 -0
- data/lib/active_support/testing/constant_lookup.rb +50 -0
- data/lib/active_support/testing/declarative.rb +26 -0
- data/lib/active_support/testing/deprecation.rb +36 -0
- data/lib/active_support/testing/file_fixtures.rb +34 -0
- data/lib/active_support/testing/isolation.rb +115 -0
- data/lib/active_support/testing/method_call_assertions.rb +41 -0
- data/lib/active_support/testing/setup_and_teardown.rb +50 -0
- data/lib/active_support/testing/stream.rb +42 -0
- data/lib/active_support/testing/tagged_logging.rb +25 -0
- data/lib/active_support/testing/time_helpers.rb +136 -0
- data/lib/active_support/time.rb +18 -0
- data/lib/active_support/time_with_zone.rb +511 -0
- data/lib/active_support/values/time_zone.rb +484 -0
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +8 -0
- data/lib/active_support/xml_mini.rb +209 -0
- data/lib/active_support/xml_mini/jdom.rb +181 -0
- data/lib/active_support/xml_mini/libxml.rb +77 -0
- data/lib/active_support/xml_mini/libxmlsax.rb +82 -0
- data/lib/active_support/xml_mini/nokogiri.rb +81 -0
- data/lib/active_support/xml_mini/nokogirisax.rb +85 -0
- data/lib/active_support/xml_mini/rexml.rb +128 -0
- metadata +350 -0
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'active_support/core_ext/module/concerning'
|
2
|
+
|
3
|
+
module Kernel
|
4
|
+
module_function
|
5
|
+
|
6
|
+
# A shortcut to define a toplevel concern, not within a module.
|
7
|
+
#
|
8
|
+
# See Module::Concerning for more.
|
9
|
+
def concern(topic, &module_definition)
|
10
|
+
Object.concern topic, &module_definition
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Kernel
|
2
|
+
module_function
|
3
|
+
|
4
|
+
# Sets $VERBOSE to nil for the duration of the block and back to its original
|
5
|
+
# value afterwards.
|
6
|
+
#
|
7
|
+
# silence_warnings do
|
8
|
+
# value = noisy_call # no warning voiced
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# noisy_call # warning voiced
|
12
|
+
def silence_warnings
|
13
|
+
with_warnings(nil) { yield }
|
14
|
+
end
|
15
|
+
|
16
|
+
# Sets $VERBOSE to +true+ for the duration of the block and back to its
|
17
|
+
# original value afterwards.
|
18
|
+
def enable_warnings
|
19
|
+
with_warnings(true) { yield }
|
20
|
+
end
|
21
|
+
|
22
|
+
# Sets $VERBOSE for the duration of the block and back to its original
|
23
|
+
# value afterwards.
|
24
|
+
def with_warnings(flag)
|
25
|
+
old_verbose, $VERBOSE = $VERBOSE, flag
|
26
|
+
yield
|
27
|
+
ensure
|
28
|
+
$VERBOSE = old_verbose
|
29
|
+
end
|
30
|
+
|
31
|
+
# Blocks and ignores any exception passed as argument if raised within the block.
|
32
|
+
#
|
33
|
+
# suppress(ZeroDivisionError) do
|
34
|
+
# 1/0
|
35
|
+
# puts 'This code is NOT reached'
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# puts 'This code gets executed and nothing related to ZeroDivisionError was seen'
|
39
|
+
def suppress(*exception_classes)
|
40
|
+
yield
|
41
|
+
rescue *exception_classes
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "active_support/deprecation"
|
2
|
+
require "active_support/deprecation/proxy_wrappers"
|
3
|
+
|
4
|
+
class LoadError
|
5
|
+
REGEXPS = [
|
6
|
+
/^no such file to load -- (.+)$/i,
|
7
|
+
/^Missing \w+ (?:file\s*)?([^\s]+.rb)$/i,
|
8
|
+
/^Missing API definition file in (.+)$/i,
|
9
|
+
/^cannot load such file -- (.+)$/i,
|
10
|
+
]
|
11
|
+
|
12
|
+
unless method_defined?(:path)
|
13
|
+
# Returns the path which was unable to be loaded.
|
14
|
+
def path
|
15
|
+
@path ||= begin
|
16
|
+
REGEXPS.find do |regex|
|
17
|
+
message =~ regex
|
18
|
+
end
|
19
|
+
$1
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns true if the given path name (except perhaps for the ".rb"
|
25
|
+
# extension) is the missing file which caused the exception to be raised.
|
26
|
+
def is_missing?(location)
|
27
|
+
location.sub(/\.rb$/, ''.freeze) == path.sub(/\.rb$/, ''.freeze)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
MissingSourceFile = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('MissingSourceFile', 'LoadError')
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ActiveSupport
|
2
|
+
module MarshalWithAutoloading # :nodoc:
|
3
|
+
def load(source, proc = nil)
|
4
|
+
super(source, proc)
|
5
|
+
rescue ArgumentError, NameError => exc
|
6
|
+
if exc.message.match(%r|undefined class/module (.+?)(?:::)?\z|)
|
7
|
+
# try loading the class/module
|
8
|
+
loaded = $1.constantize
|
9
|
+
|
10
|
+
raise unless $1 == loaded.name
|
11
|
+
|
12
|
+
# if it is an IO we need to go back to read the object
|
13
|
+
source.rewind if source.respond_to?(:rewind)
|
14
|
+
retry
|
15
|
+
else
|
16
|
+
raise exc
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Marshal.singleton_class.prepend(ActiveSupport::MarshalWithAutoloading)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'active_support/core_ext/module/aliasing'
|
2
|
+
require 'active_support/core_ext/module/introspection'
|
3
|
+
require 'active_support/core_ext/module/anonymous'
|
4
|
+
require 'active_support/core_ext/module/reachable'
|
5
|
+
require 'active_support/core_ext/module/attribute_accessors'
|
6
|
+
require 'active_support/core_ext/module/attribute_accessors_per_thread'
|
7
|
+
require 'active_support/core_ext/module/attr_internal'
|
8
|
+
require 'active_support/core_ext/module/concerning'
|
9
|
+
require 'active_support/core_ext/module/delegation'
|
10
|
+
require 'active_support/core_ext/module/deprecation'
|
11
|
+
require 'active_support/core_ext/module/remove_method'
|
12
|
+
require 'active_support/core_ext/module/qualified_const'
|
@@ -0,0 +1,74 @@
|
|
1
|
+
class Module
|
2
|
+
# NOTE: This method is deprecated. Please use <tt>Module#prepend</tt> that
|
3
|
+
# comes with Ruby 2.0 or newer instead.
|
4
|
+
#
|
5
|
+
# Encapsulates the common pattern of:
|
6
|
+
#
|
7
|
+
# alias_method :foo_without_feature, :foo
|
8
|
+
# alias_method :foo, :foo_with_feature
|
9
|
+
#
|
10
|
+
# With this, you simply do:
|
11
|
+
#
|
12
|
+
# alias_method_chain :foo, :feature
|
13
|
+
#
|
14
|
+
# And both aliases are set up for you.
|
15
|
+
#
|
16
|
+
# Query and bang methods (foo?, foo!) keep the same punctuation:
|
17
|
+
#
|
18
|
+
# alias_method_chain :foo?, :feature
|
19
|
+
#
|
20
|
+
# is equivalent to
|
21
|
+
#
|
22
|
+
# alias_method :foo_without_feature?, :foo?
|
23
|
+
# alias_method :foo?, :foo_with_feature?
|
24
|
+
#
|
25
|
+
# so you can safely chain foo, foo?, foo! and/or foo= with the same feature.
|
26
|
+
def alias_method_chain(target, feature)
|
27
|
+
ActiveSupport::Deprecation.warn("alias_method_chain is deprecated. Please, use Module#prepend instead. From module, you can access the original method using super.")
|
28
|
+
|
29
|
+
# Strip out punctuation on predicates, bang or writer methods since
|
30
|
+
# e.g. target?_without_feature is not a valid method name.
|
31
|
+
aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
|
32
|
+
yield(aliased_target, punctuation) if block_given?
|
33
|
+
|
34
|
+
with_method = "#{aliased_target}_with_#{feature}#{punctuation}"
|
35
|
+
without_method = "#{aliased_target}_without_#{feature}#{punctuation}"
|
36
|
+
|
37
|
+
alias_method without_method, target
|
38
|
+
alias_method target, with_method
|
39
|
+
|
40
|
+
case
|
41
|
+
when public_method_defined?(without_method)
|
42
|
+
public target
|
43
|
+
when protected_method_defined?(without_method)
|
44
|
+
protected target
|
45
|
+
when private_method_defined?(without_method)
|
46
|
+
private target
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Allows you to make aliases for attributes, which includes
|
51
|
+
# getter, setter, and a predicate.
|
52
|
+
#
|
53
|
+
# class Content < ActiveRecord::Base
|
54
|
+
# # has a title attribute
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
# class Email < Content
|
58
|
+
# alias_attribute :subject, :title
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# e = Email.find(1)
|
62
|
+
# e.title # => "Superstars"
|
63
|
+
# e.subject # => "Superstars"
|
64
|
+
# e.subject? # => true
|
65
|
+
# e.subject = "Megastars"
|
66
|
+
# e.title # => "Megastars"
|
67
|
+
def alias_attribute(new_name, old_name)
|
68
|
+
module_eval <<-STR, __FILE__, __LINE__ + 1
|
69
|
+
def #{new_name}; self.#{old_name}; end # def subject; self.title; end
|
70
|
+
def #{new_name}?; self.#{old_name}?; end # def subject?; self.title?; end
|
71
|
+
def #{new_name}=(v); self.#{old_name} = v; end # def subject=(v); self.title = v; end
|
72
|
+
STR
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class Module
|
2
|
+
# A module may or may not have a name.
|
3
|
+
#
|
4
|
+
# module M; end
|
5
|
+
# M.name # => "M"
|
6
|
+
#
|
7
|
+
# m = Module.new
|
8
|
+
# m.name # => nil
|
9
|
+
#
|
10
|
+
# +anonymous?+ method returns true if module does not have a name, false otherwise:
|
11
|
+
#
|
12
|
+
# Module.new.anonymous? # => true
|
13
|
+
#
|
14
|
+
# module M; end
|
15
|
+
# M.anonymous? # => false
|
16
|
+
#
|
17
|
+
# A module gets a name when it is first assigned to a constant. Either
|
18
|
+
# via the +module+ or +class+ keyword or by an explicit assignment:
|
19
|
+
#
|
20
|
+
# m = Module.new # creates an anonymous module
|
21
|
+
# m.anonymous? # => true
|
22
|
+
# M = m # m gets a name here as a side-effect
|
23
|
+
# m.name # => "M"
|
24
|
+
# m.anonymous? # => false
|
25
|
+
def anonymous?
|
26
|
+
name.nil?
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class Module
|
2
|
+
# Declares an attribute reader backed by an internally-named instance variable.
|
3
|
+
def attr_internal_reader(*attrs)
|
4
|
+
attrs.each {|attr_name| attr_internal_define(attr_name, :reader)}
|
5
|
+
end
|
6
|
+
|
7
|
+
# Declares an attribute writer backed by an internally-named instance variable.
|
8
|
+
def attr_internal_writer(*attrs)
|
9
|
+
attrs.each {|attr_name| attr_internal_define(attr_name, :writer)}
|
10
|
+
end
|
11
|
+
|
12
|
+
# Declares an attribute reader and writer backed by an internally-named instance
|
13
|
+
# variable.
|
14
|
+
def attr_internal_accessor(*attrs)
|
15
|
+
attr_internal_reader(*attrs)
|
16
|
+
attr_internal_writer(*attrs)
|
17
|
+
end
|
18
|
+
alias_method :attr_internal, :attr_internal_accessor
|
19
|
+
|
20
|
+
class << self; attr_accessor :attr_internal_naming_format end
|
21
|
+
self.attr_internal_naming_format = '@_%s'
|
22
|
+
|
23
|
+
private
|
24
|
+
def attr_internal_ivar_name(attr)
|
25
|
+
Module.attr_internal_naming_format % attr
|
26
|
+
end
|
27
|
+
|
28
|
+
def attr_internal_define(attr_name, type)
|
29
|
+
internal_name = attr_internal_ivar_name(attr_name).sub(/\A@/, '')
|
30
|
+
# use native attr_* methods as they are faster on some Ruby implementations
|
31
|
+
send("attr_#{type}", internal_name)
|
32
|
+
attr_name, internal_name = "#{attr_name}=", "#{internal_name}=" if type == :writer
|
33
|
+
alias_method attr_name, internal_name
|
34
|
+
remove_method internal_name
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,212 @@
|
|
1
|
+
require 'active_support/core_ext/array/extract_options'
|
2
|
+
|
3
|
+
# Extends the module object with class/module and instance accessors for
|
4
|
+
# class/module attributes, just like the native attr* accessors for instance
|
5
|
+
# attributes.
|
6
|
+
class Module
|
7
|
+
# Defines a class attribute and creates a class and instance reader methods.
|
8
|
+
# The underlying class variable is set to +nil+, if it is not previously
|
9
|
+
# defined.
|
10
|
+
#
|
11
|
+
# module HairColors
|
12
|
+
# mattr_reader :hair_colors
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# HairColors.hair_colors # => nil
|
16
|
+
# HairColors.class_variable_set("@@hair_colors", [:brown, :black])
|
17
|
+
# HairColors.hair_colors # => [:brown, :black]
|
18
|
+
#
|
19
|
+
# The attribute name must be a valid method name in Ruby.
|
20
|
+
#
|
21
|
+
# module Foo
|
22
|
+
# mattr_reader :"1_Badname"
|
23
|
+
# end
|
24
|
+
# # => NameError: invalid attribute name: 1_Badname
|
25
|
+
#
|
26
|
+
# If you want to opt out the creation on the instance reader method, pass
|
27
|
+
# <tt>instance_reader: false</tt> or <tt>instance_accessor: false</tt>.
|
28
|
+
#
|
29
|
+
# module HairColors
|
30
|
+
# mattr_reader :hair_colors, instance_reader: false
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# class Person
|
34
|
+
# include HairColors
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# Person.new.hair_colors # => NoMethodError
|
38
|
+
#
|
39
|
+
#
|
40
|
+
# Also, you can pass a block to set up the attribute with a default value.
|
41
|
+
#
|
42
|
+
# module HairColors
|
43
|
+
# mattr_reader :hair_colors do
|
44
|
+
# [:brown, :black, :blonde, :red]
|
45
|
+
# end
|
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)
|
54
|
+
options = syms.extract_options!
|
55
|
+
syms.each do |sym|
|
56
|
+
raise NameError.new("invalid attribute name: #{sym}") unless sym =~ /\A[_A-Za-z]\w*\z/
|
57
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
58
|
+
@@#{sym} = nil unless defined? @@#{sym}
|
59
|
+
|
60
|
+
def self.#{sym}
|
61
|
+
@@#{sym}
|
62
|
+
end
|
63
|
+
EOS
|
64
|
+
|
65
|
+
unless options[:instance_reader] == false || options[:instance_accessor] == false
|
66
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
67
|
+
def #{sym}
|
68
|
+
@@#{sym}
|
69
|
+
end
|
70
|
+
EOS
|
71
|
+
end
|
72
|
+
class_variable_set("@@#{sym}", yield) if block_given?
|
73
|
+
end
|
74
|
+
end
|
75
|
+
alias :cattr_reader :mattr_reader
|
76
|
+
|
77
|
+
# Defines a class attribute and creates a class and instance writer methods to
|
78
|
+
# allow assignment to the attribute.
|
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
|
+
# If you want to opt out 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
|
+
# Also, you can pass a block to set up the attribute with a default value.
|
107
|
+
#
|
108
|
+
# module HairColors
|
109
|
+
# mattr_writer :hair_colors do
|
110
|
+
# [:brown, :black, :blonde, :red]
|
111
|
+
# end
|
112
|
+
# end
|
113
|
+
#
|
114
|
+
# class Person
|
115
|
+
# include HairColors
|
116
|
+
# end
|
117
|
+
#
|
118
|
+
# Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red]
|
119
|
+
def mattr_writer(*syms)
|
120
|
+
options = syms.extract_options!
|
121
|
+
syms.each do |sym|
|
122
|
+
raise NameError.new("invalid attribute name: #{sym}") unless sym =~ /\A[_A-Za-z]\w*\z/
|
123
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
124
|
+
@@#{sym} = nil unless defined? @@#{sym}
|
125
|
+
|
126
|
+
def self.#{sym}=(obj)
|
127
|
+
@@#{sym} = obj
|
128
|
+
end
|
129
|
+
EOS
|
130
|
+
|
131
|
+
unless options[:instance_writer] == false || options[:instance_accessor] == false
|
132
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
133
|
+
def #{sym}=(obj)
|
134
|
+
@@#{sym} = obj
|
135
|
+
end
|
136
|
+
EOS
|
137
|
+
end
|
138
|
+
send("#{sym}=", yield) if block_given?
|
139
|
+
end
|
140
|
+
end
|
141
|
+
alias :cattr_writer :mattr_writer
|
142
|
+
|
143
|
+
# Defines both class and instance accessors for class attributes.
|
144
|
+
#
|
145
|
+
# module HairColors
|
146
|
+
# mattr_accessor :hair_colors
|
147
|
+
# end
|
148
|
+
#
|
149
|
+
# class Person
|
150
|
+
# include HairColors
|
151
|
+
# end
|
152
|
+
#
|
153
|
+
# HairColors.hair_colors = [:brown, :black, :blonde, :red]
|
154
|
+
# HairColors.hair_colors # => [:brown, :black, :blonde, :red]
|
155
|
+
# Person.new.hair_colors # => [:brown, :black, :blonde, :red]
|
156
|
+
#
|
157
|
+
# If a subclass changes the value then that would also change the value for
|
158
|
+
# parent class. Similarly if parent class changes the value then that would
|
159
|
+
# change the value of subclasses too.
|
160
|
+
#
|
161
|
+
# class Male < Person
|
162
|
+
# end
|
163
|
+
#
|
164
|
+
# Male.new.hair_colors << :blue
|
165
|
+
# Person.new.hair_colors # => [:brown, :black, :blonde, :red, :blue]
|
166
|
+
#
|
167
|
+
# To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
|
168
|
+
# To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
|
169
|
+
#
|
170
|
+
# module HairColors
|
171
|
+
# mattr_accessor :hair_colors, instance_writer: false, instance_reader: false
|
172
|
+
# end
|
173
|
+
#
|
174
|
+
# class Person
|
175
|
+
# include HairColors
|
176
|
+
# end
|
177
|
+
#
|
178
|
+
# Person.new.hair_colors = [:brown] # => NoMethodError
|
179
|
+
# Person.new.hair_colors # => NoMethodError
|
180
|
+
#
|
181
|
+
# Or pass <tt>instance_accessor: false</tt>, to opt out both instance methods.
|
182
|
+
#
|
183
|
+
# module HairColors
|
184
|
+
# mattr_accessor :hair_colors, instance_accessor: false
|
185
|
+
# end
|
186
|
+
#
|
187
|
+
# class Person
|
188
|
+
# include HairColors
|
189
|
+
# end
|
190
|
+
#
|
191
|
+
# Person.new.hair_colors = [:brown] # => NoMethodError
|
192
|
+
# Person.new.hair_colors # => NoMethodError
|
193
|
+
#
|
194
|
+
# Also you can pass a block to set up the attribute with a default value.
|
195
|
+
#
|
196
|
+
# module HairColors
|
197
|
+
# mattr_accessor :hair_colors do
|
198
|
+
# [:brown, :black, :blonde, :red]
|
199
|
+
# end
|
200
|
+
# end
|
201
|
+
#
|
202
|
+
# class Person
|
203
|
+
# include HairColors
|
204
|
+
# end
|
205
|
+
#
|
206
|
+
# Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red]
|
207
|
+
def mattr_accessor(*syms, &blk)
|
208
|
+
mattr_reader(*syms, &blk)
|
209
|
+
mattr_writer(*syms)
|
210
|
+
end
|
211
|
+
alias :cattr_accessor :mattr_accessor
|
212
|
+
end
|