activesupport 3.1.0 → 5.0.0
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 +798 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +13 -7
- data/lib/active_support/array_inquirer.rb +44 -0
- data/lib/active_support/backtrace_cleaner.rb +38 -34
- data/lib/active_support/benchmarkable.rb +17 -28
- data/lib/active_support/cache/file_store.rb +85 -70
- data/lib/active_support/cache/mem_cache_store.rb +75 -66
- data/lib/active_support/cache/memory_store.rb +31 -23
- data/lib/active_support/cache/null_store.rb +41 -0
- data/lib/active_support/cache/strategy/local_cache.rb +73 -70
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +44 -0
- data/lib/active_support/cache.rb +360 -294
- data/lib/active_support/callbacks.rb +563 -393
- data/lib/active_support/concern.rb +42 -34
- data/lib/active_support/concurrency/latch.rb +19 -0
- data/lib/active_support/concurrency/share_lock.rb +186 -0
- data/lib/active_support/configurable.rb +70 -12
- data/lib/active_support/core_ext/array/access.rb +53 -9
- data/lib/active_support/core_ext/array/conversions.rb +109 -62
- data/lib/active_support/core_ext/array/extract_options.rb +2 -2
- data/lib/active_support/core_ext/array/grouping.rb +39 -32
- 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 +16 -18
- data/lib/active_support/core_ext/array.rb +2 -2
- data/lib/active_support/core_ext/benchmark.rb +7 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -36
- data/lib/active_support/core_ext/class/attribute.rb +47 -34
- data/lib/active_support/core_ext/class/attribute_accessors.rb +4 -79
- data/lib/active_support/core_ext/class/subclasses.rb +12 -7
- data/lib/active_support/core_ext/class.rb +0 -3
- data/lib/active_support/core_ext/date/blank.rb +12 -0
- data/lib/active_support/core_ext/date/calculations.rb +57 -167
- data/lib/active_support/core_ext/date/conversions.rb +31 -42
- data/lib/active_support/core_ext/date/zones.rb +2 -10
- data/lib/active_support/core_ext/date.rb +5 -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 +18 -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 +1 -0
- data/lib/active_support/core_ext/date_time/blank.rb +12 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +132 -65
- data/lib/active_support/core_ext/date_time/compatibility.rb +5 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +36 -34
- data/lib/active_support/core_ext/date_time.rb +5 -0
- data/lib/active_support/core_ext/digest/uuid.rb +51 -0
- data/lib/active_support/core_ext/enumerable.rb +81 -74
- data/lib/active_support/core_ext/file/atomic.rb +53 -26
- data/lib/active_support/core_ext/file.rb +0 -1
- data/lib/active_support/core_ext/hash/compact.rb +20 -0
- data/lib/active_support/core_ext/hash/conversions.rb +175 -70
- data/lib/active_support/core_ext/hash/deep_merge.rb +30 -8
- data/lib/active_support/core_ext/hash/except.rb +11 -12
- data/lib/active_support/core_ext/hash/indifferent_access.rb +7 -8
- data/lib/active_support/core_ext/hash/keys.rb +147 -24
- data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -3
- data/lib/active_support/core_ext/hash/slice.rb +22 -14
- data/lib/active_support/core_ext/hash/transform_values.rb +29 -0
- data/lib/active_support/core_ext/hash.rb +2 -2
- data/lib/active_support/core_ext/integer/inflections.rb +13 -1
- data/lib/active_support/core_ext/integer/multiple.rb +4 -0
- data/lib/active_support/core_ext/integer/time.rb +12 -22
- data/lib/active_support/core_ext/kernel/agnostics.rb +2 -2
- data/lib/active_support/core_ext/kernel/concern.rb +12 -0
- data/lib/active_support/core_ext/kernel/debugger.rb +2 -15
- data/lib/active_support/core_ext/kernel/reporting.rb +12 -62
- data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -7
- data/lib/active_support/core_ext/kernel.rb +2 -3
- data/lib/active_support/core_ext/load_error.rb +14 -7
- data/lib/active_support/core_ext/marshal.rb +22 -0
- data/lib/active_support/core_ext/module/aliasing.rb +16 -12
- data/lib/active_support/core_ext/module/anonymous.rb +12 -8
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
- data/lib/active_support/core_ext/module/attribute_accessors.rb +165 -13
- 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 +141 -68
- data/lib/active_support/core_ext/module/deprecation.rb +17 -3
- data/lib/active_support/core_ext/module/introspection.rb +9 -31
- 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 +1 -3
- data/lib/active_support/core_ext/module/remove_method.rb +24 -5
- data/lib/active_support/core_ext/module.rb +3 -3
- data/lib/active_support/core_ext/name_error.rb +15 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +20 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +145 -0
- data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
- data/lib/active_support/core_ext/numeric/time.rb +31 -36
- data/lib/active_support/core_ext/numeric.rb +2 -0
- data/lib/active_support/core_ext/object/acts_like.rb +4 -4
- data/lib/active_support/core_ext/object/blank.rb +52 -18
- data/lib/active_support/core_ext/object/deep_dup.rb +53 -0
- data/lib/active_support/core_ext/object/duplicable.rb +12 -20
- data/lib/active_support/core_ext/object/inclusion.rb +13 -1
- data/lib/active_support/core_ext/object/instance_variables.rb +7 -12
- data/lib/active_support/core_ext/object/json.rb +205 -0
- data/lib/active_support/core_ext/object/to_param.rb +1 -55
- data/lib/active_support/core_ext/object/to_query.rb +66 -9
- data/lib/active_support/core_ext/object/try.rb +124 -33
- data/lib/active_support/core_ext/object/with_options.rb +37 -11
- data/lib/active_support/core_ext/object.rb +2 -1
- data/lib/active_support/core_ext/range/conversions.rb +17 -7
- data/lib/active_support/core_ext/range/each.rb +21 -0
- data/lib/active_support/core_ext/range/include_range.rb +20 -18
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/range.rb +1 -2
- data/lib/active_support/core_ext/securerandom.rb +23 -0
- data/lib/active_support/core_ext/string/access.rb +95 -90
- data/lib/active_support/core_ext/string/behavior.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +41 -38
- data/lib/active_support/core_ext/string/exclude.rb +6 -1
- data/lib/active_support/core_ext/string/filters.rb +70 -17
- data/lib/active_support/core_ext/string/indent.rb +43 -0
- data/lib/active_support/core_ext/string/inflections.rb +139 -59
- data/lib/active_support/core_ext/string/inquiry.rb +2 -2
- data/lib/active_support/core_ext/string/multibyte.rb +46 -65
- data/lib/active_support/core_ext/string/output_safety.rb +153 -56
- data/lib/active_support/core_ext/string/strip.rb +3 -6
- data/lib/active_support/core_ext/string/zones.rb +14 -0
- data/lib/active_support/core_ext/string.rb +2 -3
- data/lib/active_support/core_ext/struct.rb +3 -0
- data/lib/active_support/core_ext/time/calculations.rb +173 -173
- data/lib/active_support/core_ext/time/compatibility.rb +5 -0
- data/lib/active_support/core_ext/time/conversions.rb +33 -29
- data/lib/active_support/core_ext/time/marshal.rb +2 -56
- data/lib/active_support/core_ext/time/zones.rb +57 -32
- data/lib/active_support/core_ext/time.rb +5 -0
- data/lib/active_support/core_ext/uri.rb +13 -19
- data/lib/active_support/core_ext.rb +3 -2
- data/lib/active_support/dependencies/autoload.rb +47 -20
- data/lib/active_support/dependencies/interlock.rb +51 -0
- data/lib/active_support/dependencies.rb +315 -265
- data/lib/active_support/deprecation/behaviors.rb +71 -30
- data/lib/active_support/deprecation/instance_delegator.rb +24 -0
- data/lib/active_support/deprecation/method_wrappers.rb +59 -18
- data/lib/active_support/deprecation/proxy_wrappers.rb +82 -14
- data/lib/active_support/deprecation/reporting.rb +61 -14
- data/lib/active_support/deprecation.rb +38 -13
- data/lib/active_support/descendants_tracker.rb +34 -19
- data/lib/active_support/duration/iso8601_parser.rb +122 -0
- data/lib/active_support/duration/iso8601_serializer.rb +51 -0
- data/lib/active_support/duration.rb +85 -14
- data/lib/active_support/evented_file_update_checker.rb +194 -0
- data/lib/active_support/execution_wrapper.rb +117 -0
- data/lib/active_support/executor.rb +6 -0
- data/lib/active_support/file_update_checker.rb +138 -17
- data/lib/active_support/gem_version.rb +15 -0
- data/lib/active_support/gzip.rb +11 -5
- data/lib/active_support/hash_with_indifferent_access.rb +199 -49
- data/lib/active_support/i18n.rb +6 -2
- data/lib/active_support/i18n_railtie.rb +40 -21
- data/lib/active_support/inflections.rb +22 -13
- data/lib/active_support/inflector/inflections.rb +175 -144
- data/lib/active_support/inflector/methods.rb +328 -91
- data/lib/active_support/inflector/transliterate.rb +51 -37
- data/lib/active_support/json/decoding.rb +31 -22
- data/lib/active_support/json/encoding.rb +88 -248
- data/lib/active_support/key_generator.rb +71 -0
- data/lib/active_support/lazy_load_hooks.rb +27 -25
- data/lib/active_support/locale/en.yml +102 -3
- data/lib/active_support/log_subscriber/test_helper.rb +24 -21
- data/lib/active_support/log_subscriber.rb +36 -49
- 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 +72 -36
- data/lib/active_support/message_verifier.rb +96 -24
- data/lib/active_support/multibyte/chars.rb +88 -333
- data/lib/active_support/multibyte/unicode.rb +156 -136
- data/lib/active_support/multibyte.rb +5 -28
- data/lib/active_support/notifications/fanout.rb +115 -19
- data/lib/active_support/notifications/instrumenter.rb +52 -15
- data/lib/active_support/notifications.rb +168 -33
- 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/number_helper.rb +368 -0
- data/lib/active_support/option_merger.rb +1 -1
- data/lib/active_support/ordered_hash.rb +18 -183
- data/lib/active_support/ordered_options.rb +44 -24
- 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 +25 -34
- data/lib/active_support/reloader.rb +129 -0
- data/lib/active_support/rescuable.rb +98 -48
- data/lib/active_support/security_utils.rb +27 -0
- data/lib/active_support/string_inquirer.rb +14 -9
- data/lib/active_support/subscriber.rb +120 -0
- data/lib/active_support/tagged_logging.rb +78 -0
- data/lib/active_support/test_case.rb +69 -17
- data/lib/active_support/testing/assertions.rb +43 -41
- data/lib/active_support/testing/autorun.rb +12 -0
- data/lib/active_support/testing/constant_lookup.rb +50 -0
- data/lib/active_support/testing/declarative.rb +7 -21
- data/lib/active_support/testing/deprecation.rb +14 -33
- data/lib/active_support/testing/file_fixtures.rb +34 -0
- data/lib/active_support/testing/isolation.rb +53 -95
- data/lib/active_support/testing/method_call_assertions.rb +41 -0
- data/lib/active_support/testing/setup_and_teardown.rb +21 -82
- 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 +134 -0
- data/lib/active_support/time.rb +6 -23
- data/lib/active_support/time_with_zone.rb +239 -92
- data/lib/active_support/values/time_zone.rb +236 -160
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +5 -7
- data/lib/active_support/xml_mini/jdom.rb +19 -13
- data/lib/active_support/xml_mini/libxml.rb +3 -4
- data/lib/active_support/xml_mini/libxmlsax.rb +2 -3
- data/lib/active_support/xml_mini/nokogiri.rb +3 -4
- data/lib/active_support/xml_mini/nokogirisax.rb +2 -3
- data/lib/active_support/xml_mini/rexml.rb +8 -10
- data/lib/active_support/xml_mini.rb +66 -34
- data/lib/active_support.rb +40 -23
- metadata +185 -134
- data/CHANGELOG +0 -1534
- data/lib/active_support/base64.rb +0 -42
- data/lib/active_support/basic_object.rb +0 -21
- data/lib/active_support/buffered_logger.rb +0 -137
- data/lib/active_support/cache/compressed_mem_cache_store.rb +0 -13
- data/lib/active_support/cache/synchronized_memory_store.rb +0 -11
- data/lib/active_support/core_ext/array/random_access.rb +0 -30
- data/lib/active_support/core_ext/array/uniq_by.rb +0 -16
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -44
- data/lib/active_support/core_ext/class/inheritable_attributes.rb +0 -178
- data/lib/active_support/core_ext/date/freeze.rb +0 -31
- data/lib/active_support/core_ext/date_time/zones.rb +0 -21
- 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 -11
- data/lib/active_support/core_ext/hash/diff.rb +0 -13
- data/lib/active_support/core_ext/kernel/requires.rb +0 -28
- data/lib/active_support/core_ext/logger.rb +0 -81
- data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +0 -31
- data/lib/active_support/core_ext/module/method_names.rb +0 -14
- data/lib/active_support/core_ext/module/synchronization.rb +0 -43
- data/lib/active_support/core_ext/object/to_json.rb +0 -19
- data/lib/active_support/core_ext/proc.rb +0 -14
- 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/encoding.rb +0 -11
- 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/file_watcher.rb +0 -36
- data/lib/active_support/json/variable.rb +0 -9
- data/lib/active_support/memoizable.rb +0 -105
- 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/secure_random.rb +0 -6
- data/lib/active_support/testing/mochaing.rb +0 -7
- data/lib/active_support/testing/pending.rb +0 -52
- 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 -60
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'active_support/core_ext/big_decimal/conversions'
|
2
|
+
require 'active_support/number_helper'
|
3
|
+
require 'active_support/core_ext/module/deprecation'
|
4
|
+
|
5
|
+
module ActiveSupport::NumericWithFormat
|
6
|
+
|
7
|
+
# Provides options for converting numbers into formatted strings.
|
8
|
+
# Options are provided for phone numbers, currency, percentage,
|
9
|
+
# precision, positional notation, file size and pretty printing.
|
10
|
+
#
|
11
|
+
# ==== Options
|
12
|
+
#
|
13
|
+
# For details on which formats use which options, see ActiveSupport::NumberHelper
|
14
|
+
#
|
15
|
+
# ==== Examples
|
16
|
+
#
|
17
|
+
# Phone Numbers:
|
18
|
+
# 5551234.to_s(:phone) # => "555-1234"
|
19
|
+
# 1235551234.to_s(:phone) # => "123-555-1234"
|
20
|
+
# 1235551234.to_s(:phone, area_code: true) # => "(123) 555-1234"
|
21
|
+
# 1235551234.to_s(:phone, delimiter: ' ') # => "123 555 1234"
|
22
|
+
# 1235551234.to_s(:phone, area_code: true, extension: 555) # => "(123) 555-1234 x 555"
|
23
|
+
# 1235551234.to_s(:phone, country_code: 1) # => "+1-123-555-1234"
|
24
|
+
# 1235551234.to_s(:phone, country_code: 1, extension: 1343, delimiter: '.')
|
25
|
+
# # => "+1.123.555.1234 x 1343"
|
26
|
+
#
|
27
|
+
# Currency:
|
28
|
+
# 1234567890.50.to_s(:currency) # => "$1,234,567,890.50"
|
29
|
+
# 1234567890.506.to_s(:currency) # => "$1,234,567,890.51"
|
30
|
+
# 1234567890.506.to_s(:currency, precision: 3) # => "$1,234,567,890.506"
|
31
|
+
# 1234567890.506.to_s(:currency, locale: :fr) # => "1 234 567 890,51 €"
|
32
|
+
# -1234567890.50.to_s(:currency, negative_format: '(%u%n)')
|
33
|
+
# # => "($1,234,567,890.50)"
|
34
|
+
# 1234567890.50.to_s(:currency, unit: '£', separator: ',', delimiter: '')
|
35
|
+
# # => "£1234567890,50"
|
36
|
+
# 1234567890.50.to_s(:currency, unit: '£', separator: ',', delimiter: '', format: '%n %u')
|
37
|
+
# # => "1234567890,50 £"
|
38
|
+
#
|
39
|
+
# Percentage:
|
40
|
+
# 100.to_s(:percentage) # => "100.000%"
|
41
|
+
# 100.to_s(:percentage, precision: 0) # => "100%"
|
42
|
+
# 1000.to_s(:percentage, delimiter: '.', separator: ',') # => "1.000,000%"
|
43
|
+
# 302.24398923423.to_s(:percentage, precision: 5) # => "302.24399%"
|
44
|
+
# 1000.to_s(:percentage, locale: :fr) # => "1 000,000%"
|
45
|
+
# 100.to_s(:percentage, format: '%n %') # => "100.000 %"
|
46
|
+
#
|
47
|
+
# Delimited:
|
48
|
+
# 12345678.to_s(:delimited) # => "12,345,678"
|
49
|
+
# 12345678.05.to_s(:delimited) # => "12,345,678.05"
|
50
|
+
# 12345678.to_s(:delimited, delimiter: '.') # => "12.345.678"
|
51
|
+
# 12345678.to_s(:delimited, delimiter: ',') # => "12,345,678"
|
52
|
+
# 12345678.05.to_s(:delimited, separator: ' ') # => "12,345,678 05"
|
53
|
+
# 12345678.05.to_s(:delimited, locale: :fr) # => "12 345 678,05"
|
54
|
+
# 98765432.98.to_s(:delimited, delimiter: ' ', separator: ',')
|
55
|
+
# # => "98 765 432,98"
|
56
|
+
#
|
57
|
+
# Rounded:
|
58
|
+
# 111.2345.to_s(:rounded) # => "111.235"
|
59
|
+
# 111.2345.to_s(:rounded, precision: 2) # => "111.23"
|
60
|
+
# 13.to_s(:rounded, precision: 5) # => "13.00000"
|
61
|
+
# 389.32314.to_s(:rounded, precision: 0) # => "389"
|
62
|
+
# 111.2345.to_s(:rounded, significant: true) # => "111"
|
63
|
+
# 111.2345.to_s(:rounded, precision: 1, significant: true) # => "100"
|
64
|
+
# 13.to_s(:rounded, precision: 5, significant: true) # => "13.000"
|
65
|
+
# 111.234.to_s(:rounded, locale: :fr) # => "111,234"
|
66
|
+
# 13.to_s(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true)
|
67
|
+
# # => "13"
|
68
|
+
# 389.32314.to_s(:rounded, precision: 4, significant: true) # => "389.3"
|
69
|
+
# 1111.2345.to_s(:rounded, precision: 2, separator: ',', delimiter: '.')
|
70
|
+
# # => "1.111,23"
|
71
|
+
#
|
72
|
+
# Human-friendly size in Bytes:
|
73
|
+
# 123.to_s(:human_size) # => "123 Bytes"
|
74
|
+
# 1234.to_s(:human_size) # => "1.21 KB"
|
75
|
+
# 12345.to_s(:human_size) # => "12.1 KB"
|
76
|
+
# 1234567.to_s(:human_size) # => "1.18 MB"
|
77
|
+
# 1234567890.to_s(:human_size) # => "1.15 GB"
|
78
|
+
# 1234567890123.to_s(:human_size) # => "1.12 TB"
|
79
|
+
# 1234567890123456.to_s(:human_size) # => "1.1 PB"
|
80
|
+
# 1234567890123456789.to_s(:human_size) # => "1.07 EB"
|
81
|
+
# 1234567.to_s(:human_size, precision: 2) # => "1.2 MB"
|
82
|
+
# 483989.to_s(:human_size, precision: 2) # => "470 KB"
|
83
|
+
# 1234567.to_s(:human_size, precision: 2, separator: ',') # => "1,2 MB"
|
84
|
+
# 1234567890123.to_s(:human_size, precision: 5) # => "1.1228 TB"
|
85
|
+
# 524288000.to_s(:human_size, precision: 5) # => "500 MB"
|
86
|
+
#
|
87
|
+
# Human-friendly format:
|
88
|
+
# 123.to_s(:human) # => "123"
|
89
|
+
# 1234.to_s(:human) # => "1.23 Thousand"
|
90
|
+
# 12345.to_s(:human) # => "12.3 Thousand"
|
91
|
+
# 1234567.to_s(:human) # => "1.23 Million"
|
92
|
+
# 1234567890.to_s(:human) # => "1.23 Billion"
|
93
|
+
# 1234567890123.to_s(:human) # => "1.23 Trillion"
|
94
|
+
# 1234567890123456.to_s(:human) # => "1.23 Quadrillion"
|
95
|
+
# 1234567890123456789.to_s(:human) # => "1230 Quadrillion"
|
96
|
+
# 489939.to_s(:human, precision: 2) # => "490 Thousand"
|
97
|
+
# 489939.to_s(:human, precision: 4) # => "489.9 Thousand"
|
98
|
+
# 1234567.to_s(:human, precision: 4,
|
99
|
+
# significant: false) # => "1.2346 Million"
|
100
|
+
# 1234567.to_s(:human, precision: 1,
|
101
|
+
# separator: ',',
|
102
|
+
# significant: false) # => "1,2 Million"
|
103
|
+
def to_s(*args)
|
104
|
+
format, options = args
|
105
|
+
options ||= {}
|
106
|
+
|
107
|
+
case format
|
108
|
+
when :phone
|
109
|
+
return ActiveSupport::NumberHelper.number_to_phone(self, options)
|
110
|
+
when :currency
|
111
|
+
return ActiveSupport::NumberHelper.number_to_currency(self, options)
|
112
|
+
when :percentage
|
113
|
+
return ActiveSupport::NumberHelper.number_to_percentage(self, options)
|
114
|
+
when :delimited
|
115
|
+
return ActiveSupport::NumberHelper.number_to_delimited(self, options)
|
116
|
+
when :rounded
|
117
|
+
return ActiveSupport::NumberHelper.number_to_rounded(self, options)
|
118
|
+
when :human
|
119
|
+
return ActiveSupport::NumberHelper.number_to_human(self, options)
|
120
|
+
when :human_size
|
121
|
+
return ActiveSupport::NumberHelper.number_to_human_size(self, options)
|
122
|
+
else
|
123
|
+
if is_a?(Float) || format.is_a?(Symbol)
|
124
|
+
super()
|
125
|
+
else
|
126
|
+
super
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def to_formatted_s(*args)
|
132
|
+
to_s(*args)
|
133
|
+
end
|
134
|
+
deprecate to_formatted_s: :to_s
|
135
|
+
end
|
136
|
+
|
137
|
+
# Ruby 2.4+ unifies Fixnum & Bignum into Integer.
|
138
|
+
if Integer == Fixnum
|
139
|
+
Integer.prepend ActiveSupport::NumericWithFormat
|
140
|
+
else
|
141
|
+
Fixnum.prepend ActiveSupport::NumericWithFormat
|
142
|
+
Bignum.prepend ActiveSupport::NumericWithFormat
|
143
|
+
end
|
144
|
+
Float.prepend ActiveSupport::NumericWithFormat
|
145
|
+
BigDecimal.prepend ActiveSupport::NumericWithFormat
|
@@ -0,0 +1,26 @@
|
|
1
|
+
unless 1.respond_to?(:positive?) # TODO: Remove this file when we drop support to ruby < 2.3
|
2
|
+
class Numeric
|
3
|
+
# Returns true if the number is positive.
|
4
|
+
#
|
5
|
+
# 1.positive? # => true
|
6
|
+
# 0.positive? # => false
|
7
|
+
# -1.positive? # => false
|
8
|
+
def positive?
|
9
|
+
self > 0
|
10
|
+
end
|
11
|
+
|
12
|
+
# Returns true if the number is negative.
|
13
|
+
#
|
14
|
+
# -1.negative? # => true
|
15
|
+
# 0.negative? # => false
|
16
|
+
# 1.negative? # => false
|
17
|
+
def negative?
|
18
|
+
self < 0
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Complex
|
23
|
+
undef :positive?
|
24
|
+
undef :negative?
|
25
|
+
end
|
26
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'active_support/duration'
|
2
2
|
require 'active_support/core_ext/time/calculations'
|
3
3
|
require 'active_support/core_ext/time/acts_like'
|
4
|
+
require 'active_support/core_ext/date/calculations'
|
5
|
+
require 'active_support/core_ext/date/acts_like'
|
4
6
|
|
5
7
|
class Numeric
|
6
8
|
# Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years.
|
@@ -8,72 +10,65 @@ class Numeric
|
|
8
10
|
# These methods use Time#advance for precise date calculations when using from_now, ago, etc.
|
9
11
|
# as well as adding or subtracting their results from a Time object. For example:
|
10
12
|
#
|
11
|
-
# # equivalent to Time.
|
13
|
+
# # equivalent to Time.current.advance(months: 1)
|
12
14
|
# 1.month.from_now
|
13
15
|
#
|
14
|
-
# # equivalent to Time.
|
16
|
+
# # equivalent to Time.current.advance(years: 2)
|
15
17
|
# 2.years.from_now
|
16
18
|
#
|
17
|
-
# # equivalent to Time.
|
19
|
+
# # equivalent to Time.current.advance(months: 4, years: 5)
|
18
20
|
# (4.months + 5.years).from_now
|
19
|
-
#
|
20
|
-
# While these methods provide precise calculation when used as in the examples above, care
|
21
|
-
# should be taken to note that this is not true if the result of `months', `years', etc is
|
22
|
-
# converted before use:
|
23
|
-
#
|
24
|
-
# # equivalent to 30.days.to_i.from_now
|
25
|
-
# 1.month.to_i.from_now
|
26
|
-
#
|
27
|
-
# # equivalent to 365.25.days.to_f.from_now
|
28
|
-
# 1.year.to_f.from_now
|
29
|
-
#
|
30
|
-
# In such cases, Ruby's core
|
31
|
-
# Date[http://stdlib.rubyonrails.org/libdoc/date/rdoc/index.html] and
|
32
|
-
# Time[http://stdlib.rubyonrails.org/libdoc/time/rdoc/index.html] should be used for precision
|
33
|
-
# date and time arithmetic
|
34
21
|
def seconds
|
35
22
|
ActiveSupport::Duration.new(self, [[:seconds, self]])
|
36
23
|
end
|
37
24
|
alias :second :seconds
|
38
25
|
|
26
|
+
# Returns a Duration instance matching the number of minutes provided.
|
27
|
+
#
|
28
|
+
# 2.minutes # => 2 minutes
|
39
29
|
def minutes
|
40
|
-
ActiveSupport::Duration.new(self * 60, [[:
|
30
|
+
ActiveSupport::Duration.new(self * 60, [[:minutes, self]])
|
41
31
|
end
|
42
32
|
alias :minute :minutes
|
43
33
|
|
34
|
+
# Returns a Duration instance matching the number of hours provided.
|
35
|
+
#
|
36
|
+
# 2.hours # => 2 hours
|
44
37
|
def hours
|
45
|
-
ActiveSupport::Duration.new(self * 3600, [[:
|
38
|
+
ActiveSupport::Duration.new(self * 3600, [[:hours, self]])
|
46
39
|
end
|
47
40
|
alias :hour :hours
|
48
41
|
|
42
|
+
# Returns a Duration instance matching the number of days provided.
|
43
|
+
#
|
44
|
+
# 2.days # => 2 days
|
49
45
|
def days
|
50
46
|
ActiveSupport::Duration.new(self * 24.hours, [[:days, self]])
|
51
47
|
end
|
52
48
|
alias :day :days
|
53
49
|
|
50
|
+
# Returns a Duration instance matching the number of weeks provided.
|
51
|
+
#
|
52
|
+
# 2.weeks # => 2 weeks
|
54
53
|
def weeks
|
55
|
-
ActiveSupport::Duration.new(self * 7.days, [[:
|
54
|
+
ActiveSupport::Duration.new(self * 7.days, [[:weeks, self]])
|
56
55
|
end
|
57
56
|
alias :week :weeks
|
58
57
|
|
58
|
+
# Returns a Duration instance matching the number of fortnights provided.
|
59
|
+
#
|
60
|
+
# 2.fortnights # => 4 weeks
|
59
61
|
def fortnights
|
60
|
-
ActiveSupport::Duration.new(self * 2.weeks, [[:
|
62
|
+
ActiveSupport::Duration.new(self * 2.weeks, [[:weeks, self * 2]])
|
61
63
|
end
|
62
64
|
alias :fortnight :fortnights
|
63
65
|
|
64
|
-
#
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
# Reads best with argument: 10.minutes.since(time)
|
73
|
-
def since(time = ::Time.current)
|
74
|
-
time + self
|
66
|
+
# Returns the number of milliseconds equivalent to the seconds provided.
|
67
|
+
# Used with the standard time durations, like 1.hour.in_milliseconds --
|
68
|
+
# so we can feed them to JavaScript functions like getTime().
|
69
|
+
#
|
70
|
+
# 2.in_milliseconds # => 2_000
|
71
|
+
def in_milliseconds
|
72
|
+
self * 1000
|
75
73
|
end
|
76
|
-
|
77
|
-
# Reads best without arguments: 10.minutes.from_now
|
78
|
-
alias :from_now :since
|
79
74
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
class Object
|
2
2
|
# A duck-type assistant method. For example, Active Support extends Date
|
3
|
-
# to define an acts_like_date
|
4
|
-
# acts_like_time
|
5
|
-
#
|
6
|
-
# we want to act like Time simply need to define an acts_like_time
|
3
|
+
# to define an <tt>acts_like_date?</tt> method, and extends Time to define
|
4
|
+
# <tt>acts_like_time?</tt>. As a result, we can do <tt>x.acts_like?(:time)</tt> and
|
5
|
+
# <tt>x.acts_like?(:date)</tt> to do duck-type-safe comparisons, since classes that
|
6
|
+
# we want to act like Time simply need to define an <tt>acts_like_time?</tt> method.
|
7
7
|
def acts_like?(duck)
|
8
8
|
respond_to? :"acts_like_#{duck}?"
|
9
9
|
end
|
@@ -1,37 +1,43 @@
|
|
1
1
|
class Object
|
2
2
|
# An object is blank if it's false, empty, or a whitespace string.
|
3
|
-
# For example,
|
3
|
+
# For example, +false+, '', ' ', +nil+, [], and {} are all blank.
|
4
4
|
#
|
5
|
-
# This simplifies
|
5
|
+
# This simplifies
|
6
6
|
#
|
7
|
-
#
|
7
|
+
# !address || address.empty?
|
8
8
|
#
|
9
|
-
#
|
9
|
+
# to
|
10
10
|
#
|
11
|
-
#
|
11
|
+
# address.blank?
|
12
|
+
#
|
13
|
+
# @return [true, false]
|
12
14
|
def blank?
|
13
|
-
respond_to?(:empty?) ? empty? : !self
|
15
|
+
respond_to?(:empty?) ? !!empty? : !self
|
14
16
|
end
|
15
17
|
|
16
|
-
# An object is present if it's not
|
18
|
+
# An object is present if it's not blank.
|
19
|
+
#
|
20
|
+
# @return [true, false]
|
17
21
|
def present?
|
18
22
|
!blank?
|
19
23
|
end
|
20
24
|
|
21
|
-
# Returns
|
22
|
-
# <tt>object.presence</tt> is equivalent to
|
25
|
+
# Returns the receiver if it's present otherwise returns +nil+.
|
26
|
+
# <tt>object.presence</tt> is equivalent to
|
23
27
|
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
28
|
+
# object.present? ? object : nil
|
29
|
+
#
|
30
|
+
# For example, something like
|
27
31
|
#
|
28
32
|
# state = params[:state] if params[:state].present?
|
29
33
|
# country = params[:country] if params[:country].present?
|
30
34
|
# region = state || country || 'US'
|
31
35
|
#
|
32
|
-
#
|
36
|
+
# becomes
|
33
37
|
#
|
34
38
|
# region = params[:state].presence || params[:country].presence || 'US'
|
39
|
+
#
|
40
|
+
# @return [Object]
|
35
41
|
def presence
|
36
42
|
self if present?
|
37
43
|
end
|
@@ -42,6 +48,7 @@ class NilClass
|
|
42
48
|
#
|
43
49
|
# nil.blank? # => true
|
44
50
|
#
|
51
|
+
# @return [true]
|
45
52
|
def blank?
|
46
53
|
true
|
47
54
|
end
|
@@ -52,6 +59,7 @@ class FalseClass
|
|
52
59
|
#
|
53
60
|
# false.blank? # => true
|
54
61
|
#
|
62
|
+
# @return [true]
|
55
63
|
def blank?
|
56
64
|
true
|
57
65
|
end
|
@@ -62,6 +70,7 @@ class TrueClass
|
|
62
70
|
#
|
63
71
|
# true.blank? # => false
|
64
72
|
#
|
73
|
+
# @return [false]
|
65
74
|
def blank?
|
66
75
|
false
|
67
76
|
end
|
@@ -73,6 +82,7 @@ class Array
|
|
73
82
|
# [].blank? # => true
|
74
83
|
# [1,2,3].blank? # => false
|
75
84
|
#
|
85
|
+
# @return [true, false]
|
76
86
|
alias_method :blank?, :empty?
|
77
87
|
end
|
78
88
|
|
@@ -80,20 +90,32 @@ class Hash
|
|
80
90
|
# A hash is blank if it's empty:
|
81
91
|
#
|
82
92
|
# {}.blank? # => true
|
83
|
-
# {:
|
93
|
+
# { key: 'value' }.blank? # => false
|
84
94
|
#
|
95
|
+
# @return [true, false]
|
85
96
|
alias_method :blank?, :empty?
|
86
97
|
end
|
87
98
|
|
88
99
|
class String
|
100
|
+
BLANK_RE = /\A[[:space:]]*\z/
|
101
|
+
|
89
102
|
# A string is blank if it's empty or contains whitespaces only:
|
90
103
|
#
|
91
|
-
#
|
92
|
-
#
|
93
|
-
# "
|
104
|
+
# ''.blank? # => true
|
105
|
+
# ' '.blank? # => true
|
106
|
+
# "\t\n\r".blank? # => true
|
107
|
+
# ' blah '.blank? # => false
|
108
|
+
#
|
109
|
+
# Unicode whitespace is supported:
|
110
|
+
#
|
111
|
+
# "\u00a0".blank? # => true
|
94
112
|
#
|
113
|
+
# @return [true, false]
|
95
114
|
def blank?
|
96
|
-
|
115
|
+
# The regexp that matches blank strings is expensive. For the case of empty
|
116
|
+
# strings we can speed up this method (~3.5x) with an empty? call. The
|
117
|
+
# penalty for the rest of strings is marginal.
|
118
|
+
empty? || BLANK_RE === self
|
97
119
|
end
|
98
120
|
end
|
99
121
|
|
@@ -103,6 +125,18 @@ class Numeric #:nodoc:
|
|
103
125
|
# 1.blank? # => false
|
104
126
|
# 0.blank? # => false
|
105
127
|
#
|
128
|
+
# @return [false]
|
129
|
+
def blank?
|
130
|
+
false
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
class Time #:nodoc:
|
135
|
+
# No Time is blank:
|
136
|
+
#
|
137
|
+
# Time.now.blank? # => false
|
138
|
+
#
|
139
|
+
# @return [false]
|
106
140
|
def blank?
|
107
141
|
false
|
108
142
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'active_support/core_ext/object/duplicable'
|
2
|
+
|
3
|
+
class Object
|
4
|
+
# Returns a deep copy of object if it's duplicable. If it's
|
5
|
+
# not duplicable, returns +self+.
|
6
|
+
#
|
7
|
+
# object = Object.new
|
8
|
+
# dup = object.deep_dup
|
9
|
+
# dup.instance_variable_set(:@a, 1)
|
10
|
+
#
|
11
|
+
# object.instance_variable_defined?(:@a) # => false
|
12
|
+
# dup.instance_variable_defined?(:@a) # => true
|
13
|
+
def deep_dup
|
14
|
+
duplicable? ? dup : self
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Array
|
19
|
+
# Returns a deep copy of array.
|
20
|
+
#
|
21
|
+
# array = [1, [2, 3]]
|
22
|
+
# dup = array.deep_dup
|
23
|
+
# dup[1][2] = 4
|
24
|
+
#
|
25
|
+
# array[1][2] # => nil
|
26
|
+
# dup[1][2] # => 4
|
27
|
+
def deep_dup
|
28
|
+
map(&:deep_dup)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Hash
|
33
|
+
# Returns a deep copy of hash.
|
34
|
+
#
|
35
|
+
# hash = { a: { b: 'b' } }
|
36
|
+
# dup = hash.deep_dup
|
37
|
+
# dup[:a][:c] = 'c'
|
38
|
+
#
|
39
|
+
# hash[:a][:c] # => nil
|
40
|
+
# dup[:a][:c] # => "c"
|
41
|
+
def deep_dup
|
42
|
+
hash = dup
|
43
|
+
each_pair do |key, value|
|
44
|
+
if key.frozen? && ::String === key
|
45
|
+
hash[key] = value.deep_dup
|
46
|
+
else
|
47
|
+
hash.delete(key)
|
48
|
+
hash[key.deep_dup] = value.deep_dup
|
49
|
+
end
|
50
|
+
end
|
51
|
+
hash
|
52
|
+
end
|
53
|
+
end
|
@@ -19,7 +19,7 @@
|
|
19
19
|
class Object
|
20
20
|
# Can you safely dup this object?
|
21
21
|
#
|
22
|
-
# False for +nil+, +false+, +true+,
|
22
|
+
# False for +nil+, +false+, +true+, symbol, number, method objects;
|
23
23
|
# true otherwise.
|
24
24
|
def duplicable?
|
25
25
|
true
|
@@ -31,7 +31,6 @@ class NilClass
|
|
31
31
|
#
|
32
32
|
# nil.duplicable? # => false
|
33
33
|
# nil.dup # => TypeError: can't dup NilClass
|
34
|
-
#
|
35
34
|
def duplicable?
|
36
35
|
false
|
37
36
|
end
|
@@ -42,7 +41,6 @@ class FalseClass
|
|
42
41
|
#
|
43
42
|
# false.duplicable? # => false
|
44
43
|
# false.dup # => TypeError: can't dup FalseClass
|
45
|
-
#
|
46
44
|
def duplicable?
|
47
45
|
false
|
48
46
|
end
|
@@ -53,7 +51,6 @@ class TrueClass
|
|
53
51
|
#
|
54
52
|
# true.duplicable? # => false
|
55
53
|
# true.dup # => TypeError: can't dup TrueClass
|
56
|
-
#
|
57
54
|
def duplicable?
|
58
55
|
false
|
59
56
|
end
|
@@ -64,7 +61,6 @@ class Symbol
|
|
64
61
|
#
|
65
62
|
# :my_symbol.duplicable? # => false
|
66
63
|
# :my_symbol.dup # => TypeError: can't dup Symbol
|
67
|
-
#
|
68
64
|
def duplicable?
|
69
65
|
false
|
70
66
|
end
|
@@ -74,32 +70,28 @@ class Numeric
|
|
74
70
|
# Numbers are not duplicable:
|
75
71
|
#
|
76
72
|
# 3.duplicable? # => false
|
77
|
-
# 3.dup # => TypeError: can't dup
|
78
|
-
#
|
73
|
+
# 3.dup # => TypeError: can't dup Integer
|
79
74
|
def duplicable?
|
80
75
|
false
|
81
76
|
end
|
82
77
|
end
|
83
78
|
|
84
|
-
|
85
|
-
|
79
|
+
require 'bigdecimal'
|
80
|
+
class BigDecimal
|
81
|
+
# BigDecimals are duplicable:
|
86
82
|
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
# Note +dup+ returned the same class object.
|
83
|
+
# BigDecimal.new("1.2").duplicable? # => true
|
84
|
+
# BigDecimal.new("1.2").dup # => #<BigDecimal:...,'0.12E1',18(18)>
|
91
85
|
def duplicable?
|
92
|
-
|
86
|
+
true
|
93
87
|
end
|
94
88
|
end
|
95
89
|
|
96
|
-
class
|
97
|
-
#
|
98
|
-
#
|
99
|
-
# m = Module.new # => #<Module:0x10328b6e0>
|
100
|
-
# m.dup # => #<Module:0x10328b6e0>
|
90
|
+
class Method
|
91
|
+
# Methods are not duplicable:
|
101
92
|
#
|
102
|
-
#
|
93
|
+
# method(:puts).duplicable? # => false
|
94
|
+
# method(:puts).dup # => TypeError: allocator undefined for Method
|
103
95
|
def duplicable?
|
104
96
|
false
|
105
97
|
end
|
@@ -5,11 +5,23 @@ class Object
|
|
5
5
|
# characters = ["Konata", "Kagami", "Tsukasa"]
|
6
6
|
# "Konata".in?(characters) # => true
|
7
7
|
#
|
8
|
-
# This will throw an ArgumentError if the argument doesn't respond
|
8
|
+
# This will throw an +ArgumentError+ if the argument doesn't respond
|
9
9
|
# to +#include?+.
|
10
10
|
def in?(another_object)
|
11
11
|
another_object.include?(self)
|
12
12
|
rescue NoMethodError
|
13
13
|
raise ArgumentError.new("The parameter passed to #in? must respond to #include?")
|
14
14
|
end
|
15
|
+
|
16
|
+
# Returns the receiver if it's included in the argument otherwise returns +nil+.
|
17
|
+
# Argument must be any object which responds to +#include?+. Usage:
|
18
|
+
#
|
19
|
+
# params[:bucket_type].presence_in %w( project calendar )
|
20
|
+
#
|
21
|
+
# This will throw an +ArgumentError+ if the argument doesn't respond to +#include?+.
|
22
|
+
#
|
23
|
+
# @return [Object]
|
24
|
+
def presence_in(another_object)
|
25
|
+
self.in?(another_object) ? self : nil
|
26
|
+
end
|
15
27
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class Object
|
2
|
-
# Returns a hash that maps instance variable names without "@" to their
|
3
|
-
# corresponding values.
|
2
|
+
# Returns a hash with string keys that maps instance variable names without "@" to their
|
3
|
+
# corresponding values.
|
4
4
|
#
|
5
5
|
# class C
|
6
6
|
# def initialize(x, y)
|
@@ -9,12 +9,11 @@ class Object
|
|
9
9
|
# end
|
10
10
|
#
|
11
11
|
# C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
|
12
|
-
def instance_values
|
13
|
-
Hash[instance_variables.map { |name| [name
|
12
|
+
def instance_values
|
13
|
+
Hash[instance_variables.map { |name| [name[1..-1], instance_variable_get(name)] }]
|
14
14
|
end
|
15
15
|
|
16
|
-
# Returns an array of instance variable names including "@".
|
17
|
-
# both in Ruby 1.8 and 1.9.
|
16
|
+
# Returns an array of instance variable names as strings including "@".
|
18
17
|
#
|
19
18
|
# class C
|
20
19
|
# def initialize(x, y)
|
@@ -23,11 +22,7 @@ class Object
|
|
23
22
|
# end
|
24
23
|
#
|
25
24
|
# C.new(0, 1).instance_variable_names # => ["@y", "@x"]
|
26
|
-
|
27
|
-
|
28
|
-
instance_variables.map { |var| var.to_s }
|
29
|
-
end
|
30
|
-
else
|
31
|
-
alias_method :instance_variable_names, :instance_variables
|
25
|
+
def instance_variable_names
|
26
|
+
instance_variables.map(&:to_s)
|
32
27
|
end
|
33
28
|
end
|