activesupport 5.0.7.2
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 +1018 -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 +349 -0
@@ -0,0 +1,7 @@
|
|
1
|
+
require 'active_support/core_ext/array/wrap'
|
2
|
+
require 'active_support/core_ext/array/access'
|
3
|
+
require 'active_support/core_ext/array/conversions'
|
4
|
+
require 'active_support/core_ext/array/extract_options'
|
5
|
+
require 'active_support/core_ext/array/grouping'
|
6
|
+
require 'active_support/core_ext/array/prepend_and_append'
|
7
|
+
require 'active_support/core_ext/array/inquiry'
|
@@ -0,0 +1,90 @@
|
|
1
|
+
class Array
|
2
|
+
# Returns the tail of the array from +position+.
|
3
|
+
#
|
4
|
+
# %w( a b c d ).from(0) # => ["a", "b", "c", "d"]
|
5
|
+
# %w( a b c d ).from(2) # => ["c", "d"]
|
6
|
+
# %w( a b c d ).from(10) # => []
|
7
|
+
# %w().from(0) # => []
|
8
|
+
# %w( a b c d ).from(-2) # => ["c", "d"]
|
9
|
+
# %w( a b c ).from(-10) # => []
|
10
|
+
def from(position)
|
11
|
+
self[position, length] || []
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns the beginning of the array up to +position+.
|
15
|
+
#
|
16
|
+
# %w( a b c d ).to(0) # => ["a"]
|
17
|
+
# %w( a b c d ).to(2) # => ["a", "b", "c"]
|
18
|
+
# %w( a b c d ).to(10) # => ["a", "b", "c", "d"]
|
19
|
+
# %w().to(0) # => []
|
20
|
+
# %w( a b c d ).to(-2) # => ["a", "b", "c"]
|
21
|
+
# %w( a b c ).to(-10) # => []
|
22
|
+
def to(position)
|
23
|
+
if position >= 0
|
24
|
+
take position + 1
|
25
|
+
else
|
26
|
+
self[0..position]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns a copy of the Array without the specified elements.
|
31
|
+
#
|
32
|
+
# people = ["David", "Rafael", "Aaron", "Todd"]
|
33
|
+
# people.without "Aaron", "Todd"
|
34
|
+
# => ["David", "Rafael"]
|
35
|
+
#
|
36
|
+
# Note: This is an optimization of `Enumerable#without` that uses `Array#-`
|
37
|
+
# instead of `Array#reject` for performance reasons.
|
38
|
+
def without(*elements)
|
39
|
+
self - elements
|
40
|
+
end
|
41
|
+
|
42
|
+
# Equal to <tt>self[1]</tt>.
|
43
|
+
#
|
44
|
+
# %w( a b c d e ).second # => "b"
|
45
|
+
def second
|
46
|
+
self[1]
|
47
|
+
end
|
48
|
+
|
49
|
+
# Equal to <tt>self[2]</tt>.
|
50
|
+
#
|
51
|
+
# %w( a b c d e ).third # => "c"
|
52
|
+
def third
|
53
|
+
self[2]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Equal to <tt>self[3]</tt>.
|
57
|
+
#
|
58
|
+
# %w( a b c d e ).fourth # => "d"
|
59
|
+
def fourth
|
60
|
+
self[3]
|
61
|
+
end
|
62
|
+
|
63
|
+
# Equal to <tt>self[4]</tt>.
|
64
|
+
#
|
65
|
+
# %w( a b c d e ).fifth # => "e"
|
66
|
+
def fifth
|
67
|
+
self[4]
|
68
|
+
end
|
69
|
+
|
70
|
+
# Equal to <tt>self[41]</tt>. Also known as accessing "the reddit".
|
71
|
+
#
|
72
|
+
# (1..42).to_a.forty_two # => 42
|
73
|
+
def forty_two
|
74
|
+
self[41]
|
75
|
+
end
|
76
|
+
|
77
|
+
# Equal to <tt>self[-3]</tt>.
|
78
|
+
#
|
79
|
+
# %w( a b c d e ).third_to_last # => "c"
|
80
|
+
def third_to_last
|
81
|
+
self[-3]
|
82
|
+
end
|
83
|
+
|
84
|
+
# Equal to <tt>self[-2]</tt>.
|
85
|
+
#
|
86
|
+
# %w( a b c d e ).second_to_last # => "d"
|
87
|
+
def second_to_last
|
88
|
+
self[-2]
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,211 @@
|
|
1
|
+
require 'active_support/xml_mini'
|
2
|
+
require 'active_support/core_ext/hash/keys'
|
3
|
+
require 'active_support/core_ext/string/inflections'
|
4
|
+
require 'active_support/core_ext/object/to_param'
|
5
|
+
require 'active_support/core_ext/object/to_query'
|
6
|
+
|
7
|
+
class Array
|
8
|
+
# Converts the array to a comma-separated sentence where the last element is
|
9
|
+
# joined by the connector word.
|
10
|
+
#
|
11
|
+
# You can pass the following options to change the default behavior. If you
|
12
|
+
# pass an option key that doesn't exist in the list below, it will raise an
|
13
|
+
# <tt>ArgumentError</tt>.
|
14
|
+
#
|
15
|
+
# ==== Options
|
16
|
+
#
|
17
|
+
# * <tt>:words_connector</tt> - The sign or word used to join the elements
|
18
|
+
# in arrays with two or more elements (default: ", ").
|
19
|
+
# * <tt>:two_words_connector</tt> - The sign or word used to join the elements
|
20
|
+
# in arrays with two elements (default: " and ").
|
21
|
+
# * <tt>:last_word_connector</tt> - The sign or word used to join the last element
|
22
|
+
# in arrays with three or more elements (default: ", and ").
|
23
|
+
# * <tt>:locale</tt> - If +i18n+ is available, you can set a locale and use
|
24
|
+
# the connector options defined on the 'support.array' namespace in the
|
25
|
+
# corresponding dictionary file.
|
26
|
+
#
|
27
|
+
# ==== Examples
|
28
|
+
#
|
29
|
+
# [].to_sentence # => ""
|
30
|
+
# ['one'].to_sentence # => "one"
|
31
|
+
# ['one', 'two'].to_sentence # => "one and two"
|
32
|
+
# ['one', 'two', 'three'].to_sentence # => "one, two, and three"
|
33
|
+
#
|
34
|
+
# ['one', 'two'].to_sentence(passing: 'invalid option')
|
35
|
+
# # => ArgumentError: Unknown key: :passing. Valid keys are: :words_connector, :two_words_connector, :last_word_connector, :locale
|
36
|
+
#
|
37
|
+
# ['one', 'two'].to_sentence(two_words_connector: '-')
|
38
|
+
# # => "one-two"
|
39
|
+
#
|
40
|
+
# ['one', 'two', 'three'].to_sentence(words_connector: ' or ', last_word_connector: ' or at least ')
|
41
|
+
# # => "one or two or at least three"
|
42
|
+
#
|
43
|
+
# Using <tt>:locale</tt> option:
|
44
|
+
#
|
45
|
+
# # Given this locale dictionary:
|
46
|
+
# #
|
47
|
+
# # es:
|
48
|
+
# # support:
|
49
|
+
# # array:
|
50
|
+
# # words_connector: " o "
|
51
|
+
# # two_words_connector: " y "
|
52
|
+
# # last_word_connector: " o al menos "
|
53
|
+
#
|
54
|
+
# ['uno', 'dos'].to_sentence(locale: :es)
|
55
|
+
# # => "uno y dos"
|
56
|
+
#
|
57
|
+
# ['uno', 'dos', 'tres'].to_sentence(locale: :es)
|
58
|
+
# # => "uno o dos o al menos tres"
|
59
|
+
def to_sentence(options = {})
|
60
|
+
options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)
|
61
|
+
|
62
|
+
default_connectors = {
|
63
|
+
:words_connector => ', ',
|
64
|
+
:two_words_connector => ' and ',
|
65
|
+
:last_word_connector => ', and '
|
66
|
+
}
|
67
|
+
if defined?(I18n)
|
68
|
+
i18n_connectors = I18n.translate(:'support.array', locale: options[:locale], default: {})
|
69
|
+
default_connectors.merge!(i18n_connectors)
|
70
|
+
end
|
71
|
+
options = default_connectors.merge!(options)
|
72
|
+
|
73
|
+
case length
|
74
|
+
when 0
|
75
|
+
''
|
76
|
+
when 1
|
77
|
+
"#{self[0]}"
|
78
|
+
when 2
|
79
|
+
"#{self[0]}#{options[:two_words_connector]}#{self[1]}"
|
80
|
+
else
|
81
|
+
"#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Extends <tt>Array#to_s</tt> to convert a collection of elements into a
|
86
|
+
# comma separated id list if <tt>:db</tt> argument is given as the format.
|
87
|
+
#
|
88
|
+
# Blog.all.to_formatted_s(:db) # => "1,2,3"
|
89
|
+
# Blog.none.to_formatted_s(:db) # => "null"
|
90
|
+
# [1,2].to_formatted_s # => "[1, 2]"
|
91
|
+
def to_formatted_s(format = :default)
|
92
|
+
case format
|
93
|
+
when :db
|
94
|
+
if empty?
|
95
|
+
'null'
|
96
|
+
else
|
97
|
+
collect(&:id).join(',')
|
98
|
+
end
|
99
|
+
else
|
100
|
+
to_default_s
|
101
|
+
end
|
102
|
+
end
|
103
|
+
alias_method :to_default_s, :to_s
|
104
|
+
alias_method :to_s, :to_formatted_s
|
105
|
+
|
106
|
+
# Returns a string that represents the array in XML by invoking +to_xml+
|
107
|
+
# on each element. Active Record collections delegate their representation
|
108
|
+
# in XML to this method.
|
109
|
+
#
|
110
|
+
# All elements are expected to respond to +to_xml+, if any of them does
|
111
|
+
# not then an exception is raised.
|
112
|
+
#
|
113
|
+
# The root node reflects the class name of the first element in plural
|
114
|
+
# if all elements belong to the same type and that's not Hash:
|
115
|
+
#
|
116
|
+
# customer.projects.to_xml
|
117
|
+
#
|
118
|
+
# <?xml version="1.0" encoding="UTF-8"?>
|
119
|
+
# <projects type="array">
|
120
|
+
# <project>
|
121
|
+
# <amount type="decimal">20000.0</amount>
|
122
|
+
# <customer-id type="integer">1567</customer-id>
|
123
|
+
# <deal-date type="date">2008-04-09</deal-date>
|
124
|
+
# ...
|
125
|
+
# </project>
|
126
|
+
# <project>
|
127
|
+
# <amount type="decimal">57230.0</amount>
|
128
|
+
# <customer-id type="integer">1567</customer-id>
|
129
|
+
# <deal-date type="date">2008-04-15</deal-date>
|
130
|
+
# ...
|
131
|
+
# </project>
|
132
|
+
# </projects>
|
133
|
+
#
|
134
|
+
# Otherwise the root element is "objects":
|
135
|
+
#
|
136
|
+
# [{ foo: 1, bar: 2}, { baz: 3}].to_xml
|
137
|
+
#
|
138
|
+
# <?xml version="1.0" encoding="UTF-8"?>
|
139
|
+
# <objects type="array">
|
140
|
+
# <object>
|
141
|
+
# <bar type="integer">2</bar>
|
142
|
+
# <foo type="integer">1</foo>
|
143
|
+
# </object>
|
144
|
+
# <object>
|
145
|
+
# <baz type="integer">3</baz>
|
146
|
+
# </object>
|
147
|
+
# </objects>
|
148
|
+
#
|
149
|
+
# If the collection is empty the root element is "nil-classes" by default:
|
150
|
+
#
|
151
|
+
# [].to_xml
|
152
|
+
#
|
153
|
+
# <?xml version="1.0" encoding="UTF-8"?>
|
154
|
+
# <nil-classes type="array"/>
|
155
|
+
#
|
156
|
+
# To ensure a meaningful root element use the <tt>:root</tt> option:
|
157
|
+
#
|
158
|
+
# customer_with_no_projects.projects.to_xml(root: 'projects')
|
159
|
+
#
|
160
|
+
# <?xml version="1.0" encoding="UTF-8"?>
|
161
|
+
# <projects type="array"/>
|
162
|
+
#
|
163
|
+
# By default name of the node for the children of root is <tt>root.singularize</tt>.
|
164
|
+
# You can change it with the <tt>:children</tt> option.
|
165
|
+
#
|
166
|
+
# The +options+ hash is passed downwards:
|
167
|
+
#
|
168
|
+
# Message.all.to_xml(skip_types: true)
|
169
|
+
#
|
170
|
+
# <?xml version="1.0" encoding="UTF-8"?>
|
171
|
+
# <messages>
|
172
|
+
# <message>
|
173
|
+
# <created-at>2008-03-07T09:58:18+01:00</created-at>
|
174
|
+
# <id>1</id>
|
175
|
+
# <name>1</name>
|
176
|
+
# <updated-at>2008-03-07T09:58:18+01:00</updated-at>
|
177
|
+
# <user-id>1</user-id>
|
178
|
+
# </message>
|
179
|
+
# </messages>
|
180
|
+
#
|
181
|
+
def to_xml(options = {})
|
182
|
+
require 'active_support/builder' unless defined?(Builder)
|
183
|
+
|
184
|
+
options = options.dup
|
185
|
+
options[:indent] ||= 2
|
186
|
+
options[:builder] ||= Builder::XmlMarkup.new(indent: options[:indent])
|
187
|
+
options[:root] ||= \
|
188
|
+
if first.class != Hash && all? { |e| e.is_a?(first.class) }
|
189
|
+
underscored = ActiveSupport::Inflector.underscore(first.class.name)
|
190
|
+
ActiveSupport::Inflector.pluralize(underscored).tr('/', '_')
|
191
|
+
else
|
192
|
+
'objects'
|
193
|
+
end
|
194
|
+
|
195
|
+
builder = options[:builder]
|
196
|
+
builder.instruct! unless options.delete(:skip_instruct)
|
197
|
+
|
198
|
+
root = ActiveSupport::XmlMini.rename_key(options[:root].to_s, options)
|
199
|
+
children = options.delete(:children) || root.singularize
|
200
|
+
attributes = options[:skip_types] ? {} : { type: 'array' }
|
201
|
+
|
202
|
+
if empty?
|
203
|
+
builder.tag!(root, attributes)
|
204
|
+
else
|
205
|
+
builder.tag!(root, attributes) do
|
206
|
+
each { |value| ActiveSupport::XmlMini.to_tag(children, value, options) }
|
207
|
+
yield builder if block_given?
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Hash
|
2
|
+
# By default, only instances of Hash itself are extractable.
|
3
|
+
# Subclasses of Hash may implement this method and return
|
4
|
+
# true to declare themselves as extractable. If a Hash
|
5
|
+
# is extractable, Array#extract_options! pops it from
|
6
|
+
# the Array when it is the last element of the Array.
|
7
|
+
def extractable_options?
|
8
|
+
instance_of?(Hash)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Array
|
13
|
+
# Extracts options from a set of arguments. Removes and returns the last
|
14
|
+
# element in the array if it's a hash, otherwise returns a blank hash.
|
15
|
+
#
|
16
|
+
# def options(*args)
|
17
|
+
# args.extract_options!
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# options(1, 2) # => {}
|
21
|
+
# options(1, 2, a: :b) # => {:a=>:b}
|
22
|
+
def extract_options!
|
23
|
+
if last.is_a?(Hash) && last.extractable_options?
|
24
|
+
pop
|
25
|
+
else
|
26
|
+
{}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
class Array
|
2
|
+
# Splits or iterates over the array in groups of size +number+,
|
3
|
+
# padding any remaining slots with +fill_with+ unless it is +false+.
|
4
|
+
#
|
5
|
+
# %w(1 2 3 4 5 6 7 8 9 10).in_groups_of(3) {|group| p group}
|
6
|
+
# ["1", "2", "3"]
|
7
|
+
# ["4", "5", "6"]
|
8
|
+
# ["7", "8", "9"]
|
9
|
+
# ["10", nil, nil]
|
10
|
+
#
|
11
|
+
# %w(1 2 3 4 5).in_groups_of(2, ' ') {|group| p group}
|
12
|
+
# ["1", "2"]
|
13
|
+
# ["3", "4"]
|
14
|
+
# ["5", " "]
|
15
|
+
#
|
16
|
+
# %w(1 2 3 4 5).in_groups_of(2, false) {|group| p group}
|
17
|
+
# ["1", "2"]
|
18
|
+
# ["3", "4"]
|
19
|
+
# ["5"]
|
20
|
+
def in_groups_of(number, fill_with = nil)
|
21
|
+
if number.to_i <= 0
|
22
|
+
raise ArgumentError,
|
23
|
+
"Group size must be a positive integer, was #{number.inspect}"
|
24
|
+
end
|
25
|
+
|
26
|
+
if fill_with == false
|
27
|
+
collection = self
|
28
|
+
else
|
29
|
+
# size % number gives how many extra we have;
|
30
|
+
# subtracting from number gives how many to add;
|
31
|
+
# modulo number ensures we don't add group of just fill.
|
32
|
+
padding = (number - size % number) % number
|
33
|
+
collection = dup.concat(Array.new(padding, fill_with))
|
34
|
+
end
|
35
|
+
|
36
|
+
if block_given?
|
37
|
+
collection.each_slice(number) { |slice| yield(slice) }
|
38
|
+
else
|
39
|
+
collection.each_slice(number).to_a
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Splits or iterates over the array in +number+ of groups, padding any
|
44
|
+
# remaining slots with +fill_with+ unless it is +false+.
|
45
|
+
#
|
46
|
+
# %w(1 2 3 4 5 6 7 8 9 10).in_groups(3) {|group| p group}
|
47
|
+
# ["1", "2", "3", "4"]
|
48
|
+
# ["5", "6", "7", nil]
|
49
|
+
# ["8", "9", "10", nil]
|
50
|
+
#
|
51
|
+
# %w(1 2 3 4 5 6 7 8 9 10).in_groups(3, ' ') {|group| p group}
|
52
|
+
# ["1", "2", "3", "4"]
|
53
|
+
# ["5", "6", "7", " "]
|
54
|
+
# ["8", "9", "10", " "]
|
55
|
+
#
|
56
|
+
# %w(1 2 3 4 5 6 7).in_groups(3, false) {|group| p group}
|
57
|
+
# ["1", "2", "3"]
|
58
|
+
# ["4", "5"]
|
59
|
+
# ["6", "7"]
|
60
|
+
def in_groups(number, fill_with = nil)
|
61
|
+
# size.div number gives minor group size;
|
62
|
+
# size % number gives how many objects need extra accommodation;
|
63
|
+
# each group hold either division or division + 1 items.
|
64
|
+
division = size.div number
|
65
|
+
modulo = size % number
|
66
|
+
|
67
|
+
# create a new array avoiding dup
|
68
|
+
groups = []
|
69
|
+
start = 0
|
70
|
+
|
71
|
+
number.times do |index|
|
72
|
+
length = division + (modulo > 0 && modulo > index ? 1 : 0)
|
73
|
+
groups << last_group = slice(start, length)
|
74
|
+
last_group << fill_with if fill_with != false &&
|
75
|
+
modulo > 0 && length == division
|
76
|
+
start += length
|
77
|
+
end
|
78
|
+
|
79
|
+
if block_given?
|
80
|
+
groups.each { |g| yield(g) }
|
81
|
+
else
|
82
|
+
groups
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Divides the array into one or more subarrays based on a delimiting +value+
|
87
|
+
# or the result of an optional block.
|
88
|
+
#
|
89
|
+
# [1, 2, 3, 4, 5].split(3) # => [[1, 2], [4, 5]]
|
90
|
+
# (1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]]
|
91
|
+
def split(value = nil)
|
92
|
+
arr = self.dup
|
93
|
+
result = []
|
94
|
+
if block_given?
|
95
|
+
while (idx = arr.index { |i| yield i })
|
96
|
+
result << arr.shift(idx)
|
97
|
+
arr.shift
|
98
|
+
end
|
99
|
+
else
|
100
|
+
while (idx = arr.index(value))
|
101
|
+
result << arr.shift(idx)
|
102
|
+
arr.shift
|
103
|
+
end
|
104
|
+
end
|
105
|
+
result << arr
|
106
|
+
end
|
107
|
+
end
|