activesupport 7.0.3.1 → 7.2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +261 -246
- data/MIT-LICENSE +1 -1
- data/README.rdoc +7 -7
- data/lib/active_support/actionable_error.rb +3 -1
- data/lib/active_support/array_inquirer.rb +3 -1
- data/lib/active_support/backtrace_cleaner.rb +39 -7
- data/lib/active_support/benchmarkable.rb +1 -0
- data/lib/active_support/broadcast_logger.rb +238 -0
- data/lib/active_support/builder.rb +1 -1
- data/lib/active_support/cache/coder.rb +153 -0
- data/lib/active_support/cache/entry.rb +134 -0
- data/lib/active_support/cache/file_store.rb +51 -19
- data/lib/active_support/cache/mem_cache_store.rb +114 -134
- data/lib/active_support/cache/memory_store.rb +85 -30
- data/lib/active_support/cache/null_store.rb +8 -2
- data/lib/active_support/cache/redis_cache_store.rb +175 -154
- data/lib/active_support/cache/serializer_with_fallback.rb +152 -0
- data/lib/active_support/cache/strategy/local_cache.rb +64 -13
- data/lib/active_support/cache.rb +455 -378
- data/lib/active_support/callbacks.rb +121 -136
- data/lib/active_support/code_generator.rb +15 -10
- data/lib/active_support/concern.rb +4 -2
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +42 -3
- data/lib/active_support/concurrency/null_lock.rb +13 -0
- data/lib/active_support/configurable.rb +10 -0
- data/lib/active_support/core_ext/array/conversions.rb +1 -2
- data/lib/active_support/core_ext/array.rb +0 -1
- data/lib/active_support/core_ext/benchmark.rb +1 -0
- data/lib/active_support/core_ext/class/attribute.rb +2 -2
- data/lib/active_support/core_ext/class/subclasses.rb +17 -34
- data/lib/active_support/core_ext/date/blank.rb +4 -0
- data/lib/active_support/core_ext/date/calculations.rb +15 -0
- data/lib/active_support/core_ext/date/conversions.rb +1 -2
- data/lib/active_support/core_ext/date.rb +0 -1
- data/lib/active_support/core_ext/date_and_time/calculations.rb +10 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +28 -1
- data/lib/active_support/core_ext/date_time/blank.rb +4 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +4 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +6 -4
- data/lib/active_support/core_ext/date_time.rb +0 -1
- data/lib/active_support/core_ext/digest/uuid.rb +7 -10
- data/lib/active_support/core_ext/enumerable.rb +25 -80
- data/lib/active_support/core_ext/erb/util.rb +201 -0
- data/lib/active_support/core_ext/hash/conversions.rb +1 -1
- data/lib/active_support/core_ext/hash/deep_merge.rb +22 -14
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +3 -3
- data/lib/active_support/core_ext/hash/keys.rb +7 -7
- data/lib/active_support/core_ext/integer/inflections.rb +12 -12
- data/lib/active_support/core_ext/module/attr_internal.rb +17 -6
- data/lib/active_support/core_ext/module/attribute_accessors.rb +6 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +34 -16
- data/lib/active_support/core_ext/module/concerning.rb +6 -6
- data/lib/active_support/core_ext/module/delegation.rb +20 -119
- data/lib/active_support/core_ext/module/deprecation.rb +12 -12
- data/lib/active_support/core_ext/module/introspection.rb +3 -1
- data/lib/active_support/core_ext/numeric/bytes.rb +9 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +5 -3
- data/lib/active_support/core_ext/numeric.rb +0 -1
- data/lib/active_support/core_ext/object/blank.rb +45 -1
- data/lib/active_support/core_ext/object/deep_dup.rb +16 -0
- data/lib/active_support/core_ext/object/duplicable.rb +25 -16
- data/lib/active_support/core_ext/object/inclusion.rb +13 -5
- data/lib/active_support/core_ext/object/instance_variables.rb +4 -2
- data/lib/active_support/core_ext/object/json.rb +17 -7
- data/lib/active_support/core_ext/object/to_query.rb +0 -2
- data/lib/active_support/core_ext/object/try.rb +2 -2
- data/lib/active_support/core_ext/object/with.rb +46 -0
- data/lib/active_support/core_ext/object/with_options.rb +9 -9
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/pathname/blank.rb +20 -0
- data/lib/active_support/core_ext/pathname/existence.rb +2 -0
- data/lib/active_support/core_ext/pathname.rb +1 -0
- data/lib/active_support/core_ext/range/conversions.rb +28 -7
- data/lib/active_support/core_ext/range/overlap.rb +40 -0
- data/lib/active_support/core_ext/range/sole.rb +17 -0
- data/lib/active_support/core_ext/range.rb +2 -2
- data/lib/active_support/core_ext/securerandom.rb +24 -12
- data/lib/active_support/core_ext/string/conversions.rb +1 -1
- data/lib/active_support/core_ext/string/filters.rb +24 -18
- data/lib/active_support/core_ext/string/indent.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +16 -9
- data/lib/active_support/core_ext/string/multibyte.rb +3 -3
- data/lib/active_support/core_ext/string/output_safety.rb +41 -178
- data/lib/active_support/core_ext/thread/backtrace/location.rb +12 -0
- data/lib/active_support/core_ext/time/calculations.rb +40 -30
- data/lib/active_support/core_ext/time/compatibility.rb +24 -0
- data/lib/active_support/core_ext/time/conversions.rb +1 -3
- data/lib/active_support/core_ext/time/zones.rb +7 -8
- data/lib/active_support/core_ext/time.rb +0 -1
- data/lib/active_support/core_ext.rb +0 -1
- data/lib/active_support/current_attributes.rb +60 -46
- data/lib/active_support/deep_mergeable.rb +53 -0
- data/lib/active_support/delegation.rb +202 -0
- data/lib/active_support/dependencies/autoload.rb +9 -16
- data/lib/active_support/deprecation/behaviors.rb +64 -41
- data/lib/active_support/deprecation/constant_accessor.rb +47 -25
- data/lib/active_support/deprecation/deprecators.rb +104 -0
- data/lib/active_support/deprecation/disallowed.rb +6 -8
- data/lib/active_support/deprecation/method_wrappers.rb +6 -23
- data/lib/active_support/deprecation/proxy_wrappers.rb +34 -22
- data/lib/active_support/deprecation/reporting.rb +49 -27
- data/lib/active_support/deprecation.rb +39 -9
- data/lib/active_support/deprecator.rb +7 -0
- data/lib/active_support/descendants_tracker.rb +66 -172
- data/lib/active_support/duration/iso8601_parser.rb +2 -2
- data/lib/active_support/duration/iso8601_serializer.rb +1 -4
- data/lib/active_support/duration.rb +13 -7
- data/lib/active_support/encrypted_configuration.rb +63 -11
- data/lib/active_support/encrypted_file.rb +29 -13
- data/lib/active_support/environment_inquirer.rb +22 -2
- data/lib/active_support/error_reporter/test_helper.rb +15 -0
- data/lib/active_support/error_reporter.rb +163 -36
- data/lib/active_support/evented_file_update_checker.rb +17 -3
- data/lib/active_support/execution_wrapper.rb +5 -6
- data/lib/active_support/file_update_checker.rb +6 -4
- data/lib/active_support/fork_tracker.rb +4 -32
- data/lib/active_support/gem_version.rb +2 -2
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +50 -30
- data/lib/active_support/html_safe_translation.rb +19 -6
- data/lib/active_support/i18n.rb +1 -1
- data/lib/active_support/i18n_railtie.rb +20 -13
- data/lib/active_support/inflector/inflections.rb +2 -0
- data/lib/active_support/inflector/methods.rb +28 -18
- data/lib/active_support/inflector/transliterate.rb +3 -1
- data/lib/active_support/isolated_execution_state.rb +26 -22
- data/lib/active_support/json/decoding.rb +3 -2
- data/lib/active_support/json/encoding.rb +48 -48
- data/lib/active_support/key_generator.rb +9 -1
- data/lib/active_support/lazy_load_hooks.rb +22 -7
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber.rb +74 -34
- data/lib/active_support/logger.rb +22 -59
- data/lib/active_support/logger_thread_safe_level.rb +10 -32
- data/lib/active_support/message_encryptor.rb +197 -53
- data/lib/active_support/message_encryptors.rb +141 -0
- data/lib/active_support/message_pack/cache_serializer.rb +23 -0
- data/lib/active_support/message_pack/extensions.rb +305 -0
- data/lib/active_support/message_pack/serializer.rb +63 -0
- data/lib/active_support/message_pack.rb +50 -0
- data/lib/active_support/message_verifier.rb +229 -89
- data/lib/active_support/message_verifiers.rb +137 -0
- data/lib/active_support/messages/codec.rb +65 -0
- data/lib/active_support/messages/metadata.rb +111 -45
- data/lib/active_support/messages/rotation_coordinator.rb +93 -0
- data/lib/active_support/messages/rotator.rb +38 -31
- data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
- data/lib/active_support/multibyte/chars.rb +8 -3
- data/lib/active_support/multibyte/unicode.rb +9 -37
- data/lib/active_support/notifications/fanout.rb +248 -87
- data/lib/active_support/notifications/instrumenter.rb +93 -25
- data/lib/active_support/notifications.rb +36 -29
- data/lib/active_support/number_helper/number_converter.rb +16 -7
- data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -6
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +17 -2
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -3
- data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -0
- data/lib/active_support/number_helper.rb +379 -317
- data/lib/active_support/option_merger.rb +4 -4
- data/lib/active_support/ordered_hash.rb +3 -3
- data/lib/active_support/ordered_options.rb +67 -15
- data/lib/active_support/parameter_filter.rb +103 -84
- data/lib/active_support/proxy_object.rb +8 -3
- data/lib/active_support/railtie.rb +25 -20
- data/lib/active_support/reloader.rb +12 -4
- data/lib/active_support/rescuable.rb +10 -8
- data/lib/active_support/secure_compare_rotator.rb +16 -9
- data/lib/active_support/string_inquirer.rb +4 -2
- data/lib/active_support/subscriber.rb +10 -27
- data/lib/active_support/syntax_error_proxy.rb +60 -0
- data/lib/active_support/tagged_logging.rb +64 -40
- data/lib/active_support/test_case.rb +160 -7
- data/lib/active_support/testing/assertions.rb +28 -12
- data/lib/active_support/testing/autorun.rb +0 -2
- data/lib/active_support/testing/constant_stubbing.rb +54 -0
- data/lib/active_support/testing/deprecation.rb +20 -27
- data/lib/active_support/testing/error_reporter_assertions.rb +107 -0
- data/lib/active_support/testing/isolation.rb +46 -33
- data/lib/active_support/testing/method_call_assertions.rb +7 -8
- data/lib/active_support/testing/parallelization/server.rb +18 -2
- data/lib/active_support/testing/parallelization/worker.rb +2 -2
- data/lib/active_support/testing/parallelization.rb +12 -1
- data/lib/active_support/testing/parallelize_executor.rb +8 -3
- data/lib/active_support/testing/setup_and_teardown.rb +2 -0
- data/lib/active_support/testing/stream.rb +1 -1
- data/lib/active_support/testing/tests_without_assertions.rb +19 -0
- data/lib/active_support/testing/time_helpers.rb +38 -16
- data/lib/active_support/time_with_zone.rb +18 -44
- data/lib/active_support/values/time_zone.rb +25 -14
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +3 -10
- data/lib/active_support/xml_mini/nokogiri.rb +1 -1
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
- data/lib/active_support/xml_mini/rexml.rb +1 -1
- data/lib/active_support/xml_mini.rb +14 -3
- data/lib/active_support.rb +15 -3
- metadata +148 -24
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +0 -25
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +0 -26
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +0 -22
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +0 -60
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +0 -26
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +0 -7
- data/lib/active_support/core_ext/range/overlaps.rb +0 -10
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +0 -22
- data/lib/active_support/core_ext/uri.rb +0 -5
- data/lib/active_support/deprecation/instance_delegator.rb +0 -38
- data/lib/active_support/per_thread_registry.rb +0 -65
- data/lib/active_support/ruby_features.rb +0 -7
|
@@ -1,41 +1,24 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "active_support/
|
|
3
|
+
require "active_support/descendants_tracker"
|
|
4
4
|
|
|
5
5
|
class Class
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
# C.descendants # => []
|
|
11
|
-
#
|
|
12
|
-
# class B < C; end
|
|
13
|
-
# C.descendants # => [B]
|
|
14
|
-
#
|
|
15
|
-
# class A < B; end
|
|
16
|
-
# C.descendants # => [B, A]
|
|
17
|
-
#
|
|
18
|
-
# class D < C; end
|
|
19
|
-
# C.descendants # => [B, A, D]
|
|
20
|
-
def descendants
|
|
21
|
-
subclasses.concat(subclasses.flat_map(&:descendants))
|
|
22
|
-
end
|
|
23
|
-
else
|
|
24
|
-
def descendants
|
|
25
|
-
ObjectSpace.each_object(singleton_class).reject do |k|
|
|
26
|
-
k.singleton_class? || k == self
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# Returns an array with the direct children of +self+.
|
|
6
|
+
# Returns an array with all classes that are < than its receiver.
|
|
7
|
+
#
|
|
8
|
+
# class C; end
|
|
9
|
+
# C.descendants # => []
|
|
32
10
|
#
|
|
33
|
-
# class
|
|
34
|
-
#
|
|
35
|
-
# class Baz < Bar; end
|
|
11
|
+
# class B < C; end
|
|
12
|
+
# C.descendants # => [B]
|
|
36
13
|
#
|
|
37
|
-
#
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
14
|
+
# class A < B; end
|
|
15
|
+
# C.descendants # => [B, A]
|
|
16
|
+
#
|
|
17
|
+
# class D < C; end
|
|
18
|
+
# C.descendants # => [B, A, D]
|
|
19
|
+
def descendants
|
|
20
|
+
subclasses.concat(subclasses.flat_map(&:descendants))
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
prepend ActiveSupport::DescendantsTracker::ReloadedClassesFiltering
|
|
41
24
|
end
|
|
@@ -109,6 +109,21 @@ class Date
|
|
|
109
109
|
|
|
110
110
|
# Provides precise Date calculations for years, months, and days. The +options+ parameter takes a hash with
|
|
111
111
|
# any of these keys: <tt>:years</tt>, <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>.
|
|
112
|
+
#
|
|
113
|
+
# The increments are applied in order of time units from largest to smallest.
|
|
114
|
+
# In other words, the date is incremented first by +:years+, then by
|
|
115
|
+
# +:months+, then by +:weeks+, then by +:days+. This order can affect the
|
|
116
|
+
# result around the end of a month. For example, incrementing first by months
|
|
117
|
+
# then by days:
|
|
118
|
+
#
|
|
119
|
+
# Date.new(2004, 9, 30).advance(months: 1, days: 1)
|
|
120
|
+
# # => Sun, 31 Oct 2004
|
|
121
|
+
#
|
|
122
|
+
# Whereas incrementing first by days then by months yields a different result:
|
|
123
|
+
#
|
|
124
|
+
# Date.new(2004, 9, 30).advance(days: 1).advance(months: 1)
|
|
125
|
+
# # => Mon, 01 Nov 2004
|
|
126
|
+
#
|
|
112
127
|
def advance(options)
|
|
113
128
|
d = self
|
|
114
129
|
|
|
@@ -52,11 +52,10 @@ class Date
|
|
|
52
52
|
strftime(formatter)
|
|
53
53
|
end
|
|
54
54
|
else
|
|
55
|
-
|
|
55
|
+
to_s
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
58
|
alias_method :to_formatted_s, :to_fs
|
|
59
|
-
alias_method :to_default_s, :to_s
|
|
60
59
|
|
|
61
60
|
# Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005"
|
|
62
61
|
def readable_inspect
|
|
@@ -4,5 +4,4 @@ require "active_support/core_ext/date/acts_like"
|
|
|
4
4
|
require "active_support/core_ext/date/blank"
|
|
5
5
|
require "active_support/core_ext/date/calculations"
|
|
6
6
|
require "active_support/core_ext/date/conversions"
|
|
7
|
-
require "active_support/core_ext/date/deprecated_conversions" unless ENV["RAILS_DISABLE_DEPRECATED_TO_S_CONVERSION"]
|
|
8
7
|
require "active_support/core_ext/date/zones"
|
|
@@ -157,6 +157,16 @@ module DateAndTime
|
|
|
157
157
|
end
|
|
158
158
|
alias :at_end_of_quarter :end_of_quarter
|
|
159
159
|
|
|
160
|
+
# Returns the quarter for a date/time.
|
|
161
|
+
#
|
|
162
|
+
# Date.new(2010, 1, 31).quarter # => 1
|
|
163
|
+
# Date.new(2010, 4, 12).quarter # => 2
|
|
164
|
+
# Date.new(2010, 9, 15).quarter # => 3
|
|
165
|
+
# Date.new(2010, 12, 25).quarter # => 4
|
|
166
|
+
def quarter
|
|
167
|
+
(month / 3.0).ceil
|
|
168
|
+
end
|
|
169
|
+
|
|
160
170
|
# Returns a new date/time at the beginning of the year.
|
|
161
171
|
#
|
|
162
172
|
# today = Date.today # => Fri, 10 Jul 2015
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "active_support/core_ext/module/attribute_accessors"
|
|
4
|
+
require "active_support/core_ext/module/redefine_method"
|
|
4
5
|
|
|
5
6
|
module DateAndTime
|
|
6
7
|
module Compatibility
|
|
@@ -11,7 +12,33 @@ module DateAndTime
|
|
|
11
12
|
# of the receiver. For backwards compatibility we're overriding
|
|
12
13
|
# this behavior, but new apps will have an initializer that sets
|
|
13
14
|
# this to true, because the new behavior is preferred.
|
|
14
|
-
mattr_accessor :preserve_timezone,
|
|
15
|
+
mattr_accessor :preserve_timezone, instance_accessor: false, default: nil
|
|
16
|
+
|
|
17
|
+
singleton_class.silence_redefinition_of_method :preserve_timezone
|
|
18
|
+
|
|
19
|
+
#--
|
|
20
|
+
# This re-implements the behaviour of the mattr_reader, instead
|
|
21
|
+
# of prepending on to it, to avoid overcomplicating a module that
|
|
22
|
+
# is in turn included in several places. This will all go away in
|
|
23
|
+
# Rails 8.0 anyway.
|
|
24
|
+
def self.preserve_timezone # :nodoc:
|
|
25
|
+
if @@preserve_timezone.nil?
|
|
26
|
+
# Only warn once, the first time the value is used (which should
|
|
27
|
+
# be the first time #to_time is called).
|
|
28
|
+
ActiveSupport.deprecator.warn(
|
|
29
|
+
"to_time will always preserve the timezone offset of the receiver in Rails 8.0. " \
|
|
30
|
+
"To opt in to the new behavior, set `ActiveSupport.to_time_preserves_timezone = true`."
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
@@preserve_timezone = false
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
@@preserve_timezone
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def preserve_timezone # :nodoc:
|
|
40
|
+
Compatibility.preserve_timezone
|
|
41
|
+
end
|
|
15
42
|
|
|
16
43
|
# Change the output of <tt>ActiveSupport::TimeZone.utc_to_local</tt>.
|
|
17
44
|
#
|
|
@@ -75,6 +75,10 @@ class DateTime
|
|
|
75
75
|
# The +options+ parameter takes a hash with any of these keys: <tt>:years</tt>,
|
|
76
76
|
# <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>,
|
|
77
77
|
# <tt>:minutes</tt>, <tt>:seconds</tt>.
|
|
78
|
+
#
|
|
79
|
+
# Just like Date#advance, increments are applied in order of time units from
|
|
80
|
+
# largest to smallest. This order can affect the result around the end of a
|
|
81
|
+
# month.
|
|
78
82
|
def advance(options)
|
|
79
83
|
unless options[:weeks].nil?
|
|
80
84
|
options[:weeks], partial_weeks = options[:weeks].divmod(1)
|
|
@@ -11,7 +11,8 @@ class DateTime
|
|
|
11
11
|
#
|
|
12
12
|
# This method is aliased to <tt>to_formatted_s</tt>.
|
|
13
13
|
#
|
|
14
|
-
#
|
|
14
|
+
# ==== Examples
|
|
15
|
+
#
|
|
15
16
|
# datetime = DateTime.civil(2007, 12, 4, 0, 0, 0, 0) # => Tue, 04 Dec 2007 00:00:00 +0000
|
|
16
17
|
#
|
|
17
18
|
# datetime.to_fs(:db) # => "2007-12-04 00:00:00"
|
|
@@ -23,7 +24,8 @@ class DateTime
|
|
|
23
24
|
# datetime.to_fs(:rfc822) # => "Tue, 04 Dec 2007 00:00:00 +0000"
|
|
24
25
|
# datetime.to_fs(:iso8601) # => "2007-12-04T00:00:00+00:00"
|
|
25
26
|
#
|
|
26
|
-
#
|
|
27
|
+
# ==== Adding your own datetime formats to +to_fs+
|
|
28
|
+
#
|
|
27
29
|
# DateTime formats are shared with Time. You can add your own to the
|
|
28
30
|
# Time::DATE_FORMATS hash. Use the format name as the hash key and
|
|
29
31
|
# either a strftime string or Proc instance that takes a time or
|
|
@@ -36,11 +38,11 @@ class DateTime
|
|
|
36
38
|
if formatter = ::Time::DATE_FORMATS[format]
|
|
37
39
|
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
|
|
38
40
|
else
|
|
39
|
-
|
|
41
|
+
to_s
|
|
40
42
|
end
|
|
41
43
|
end
|
|
42
44
|
alias_method :to_formatted_s, :to_fs
|
|
43
|
-
|
|
45
|
+
|
|
44
46
|
|
|
45
47
|
# Returns a formatted string of the offset from UTC, or an alternative
|
|
46
48
|
# string if the time zone is already UTC.
|
|
@@ -5,4 +5,3 @@ require "active_support/core_ext/date_time/blank"
|
|
|
5
5
|
require "active_support/core_ext/date_time/calculations"
|
|
6
6
|
require "active_support/core_ext/date_time/compatibility"
|
|
7
7
|
require "active_support/core_ext/date_time/conversions"
|
|
8
|
-
require "active_support/core_ext/date_time/deprecated_conversions" unless ENV["RAILS_DISABLE_DEPRECATED_TO_S_CONVERSION"]
|
|
@@ -10,8 +10,6 @@ module Digest
|
|
|
10
10
|
OID_NAMESPACE = "k\xA7\xB8\x12\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" # :nodoc:
|
|
11
11
|
X500_NAMESPACE = "k\xA7\xB8\x14\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" # :nodoc:
|
|
12
12
|
|
|
13
|
-
mattr_accessor :use_rfc4122_namespaced_uuids, instance_accessor: false, default: false
|
|
14
|
-
|
|
15
13
|
# Generates a v5 non-random UUID (Universally Unique IDentifier).
|
|
16
14
|
#
|
|
17
15
|
# Using OpenSSL::Digest::MD5 generates version 3 UUIDs; OpenSSL::Digest::SHA1 generates version 5 UUIDs.
|
|
@@ -55,22 +53,21 @@ module Digest
|
|
|
55
53
|
SecureRandom.uuid
|
|
56
54
|
end
|
|
57
55
|
|
|
56
|
+
# Returns the nil UUID. This is a special form of UUID that is specified to
|
|
57
|
+
# have all 128 bits set to zero.
|
|
58
|
+
def self.nil_uuid
|
|
59
|
+
"00000000-0000-0000-0000-000000000000"
|
|
60
|
+
end
|
|
61
|
+
|
|
58
62
|
def self.pack_uuid_namespace(namespace)
|
|
59
63
|
if [DNS_NAMESPACE, OID_NAMESPACE, URL_NAMESPACE, X500_NAMESPACE].include?(namespace)
|
|
60
64
|
namespace
|
|
61
|
-
|
|
65
|
+
else
|
|
62
66
|
match_data = namespace.match(/\A(\h{8})-(\h{4})-(\h{4})-(\h{4})-(\h{4})(\h{8})\z/)
|
|
63
67
|
|
|
64
68
|
raise ArgumentError, "Only UUIDs are valid namespace identifiers" unless match_data.present?
|
|
65
69
|
|
|
66
70
|
match_data.captures.map { |s| s.to_i(16) }.pack("NnnnnN")
|
|
67
|
-
else
|
|
68
|
-
ActiveSupport::Deprecation.warn <<~WARNING.squish
|
|
69
|
-
Providing a namespace ID that is not one of the constants defined on Digest::UUID generates an incorrect UUID value according to RFC 4122.
|
|
70
|
-
To enable the correct behavior, set the Rails.application.config.active_support.use_rfc4122_namespaced_uuids configuration option to true.
|
|
71
|
-
WARNING
|
|
72
|
-
|
|
73
|
-
namespace
|
|
74
71
|
end
|
|
75
72
|
end
|
|
76
73
|
|
|
@@ -25,18 +25,6 @@ module Enumerable
|
|
|
25
25
|
ActiveSupport::EnumerableCoreExt::SoleItemExpectedError = remove_const(:SoleItemExpectedError)
|
|
26
26
|
singleton_class.prepend(ActiveSupport::EnumerableCoreExt::Constants)
|
|
27
27
|
|
|
28
|
-
# Enumerable#sum was added in Ruby 2.4, but it only works with Numeric elements
|
|
29
|
-
# when we omit an identity.
|
|
30
|
-
|
|
31
|
-
# :stopdoc:
|
|
32
|
-
|
|
33
|
-
# We can't use Refinements here because Refinements with Module which will be prepended
|
|
34
|
-
# doesn't work well https://bugs.ruby-lang.org/issues/13446
|
|
35
|
-
alias :_original_sum_with_required_identity :sum
|
|
36
|
-
private :_original_sum_with_required_identity
|
|
37
|
-
|
|
38
|
-
# :startdoc:
|
|
39
|
-
|
|
40
28
|
# Calculates the minimum from the extracted elements.
|
|
41
29
|
#
|
|
42
30
|
# payments = [Payment.new(5), Payment.new(15), Payment.new(10)]
|
|
@@ -53,45 +41,6 @@ module Enumerable
|
|
|
53
41
|
map(&key).max
|
|
54
42
|
end
|
|
55
43
|
|
|
56
|
-
# Calculates a sum from the elements.
|
|
57
|
-
#
|
|
58
|
-
# payments.sum { |p| p.price * p.tax_rate }
|
|
59
|
-
# payments.sum(&:price)
|
|
60
|
-
#
|
|
61
|
-
# The latter is a shortcut for:
|
|
62
|
-
#
|
|
63
|
-
# payments.inject(0) { |sum, p| sum + p.price }
|
|
64
|
-
#
|
|
65
|
-
# It can also calculate the sum without the use of a block.
|
|
66
|
-
#
|
|
67
|
-
# [5, 15, 10].sum # => 30
|
|
68
|
-
# ['foo', 'bar'].sum('') # => "foobar"
|
|
69
|
-
# [[1, 2], [3, 1, 5]].sum([]) # => [1, 2, 3, 1, 5]
|
|
70
|
-
#
|
|
71
|
-
# The default sum of an empty list is zero. You can override this default:
|
|
72
|
-
#
|
|
73
|
-
# [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
|
|
74
|
-
def sum(identity = nil, &block)
|
|
75
|
-
if identity
|
|
76
|
-
_original_sum_with_required_identity(identity, &block)
|
|
77
|
-
elsif block_given?
|
|
78
|
-
map(&block).sum
|
|
79
|
-
# we check `first(1) == []` to check if we have an
|
|
80
|
-
# empty Enumerable; checking `empty?` would return
|
|
81
|
-
# true for `[nil]`, which we want to deprecate to
|
|
82
|
-
# keep consistent with Ruby
|
|
83
|
-
elsif first.is_a?(Numeric) || first(1) == []
|
|
84
|
-
identity ||= 0
|
|
85
|
-
_original_sum_with_required_identity(identity, &block)
|
|
86
|
-
else
|
|
87
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
|
88
|
-
Rails 7.0 has deprecated Enumerable.sum in favor of Ruby's native implementation available since 2.4.
|
|
89
|
-
Sum of non-numeric elements requires an initial argument.
|
|
90
|
-
MSG
|
|
91
|
-
inject(:+) || 0
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
44
|
# Convert an enumerable to a hash, using the block result as the key and the
|
|
96
45
|
# element as the value.
|
|
97
46
|
#
|
|
@@ -144,8 +93,8 @@ module Enumerable
|
|
|
144
93
|
def many?
|
|
145
94
|
cnt = 0
|
|
146
95
|
if block_given?
|
|
147
|
-
any? do |
|
|
148
|
-
cnt += 1 if yield
|
|
96
|
+
any? do |*args|
|
|
97
|
+
cnt += 1 if yield(*args)
|
|
149
98
|
cnt > 1
|
|
150
99
|
end
|
|
151
100
|
else
|
|
@@ -225,8 +174,8 @@ module Enumerable
|
|
|
225
174
|
# [1, "", nil, 2, " ", [], {}, false, true].compact_blank
|
|
226
175
|
# # => [1, 2, true]
|
|
227
176
|
#
|
|
228
|
-
# Set.new([nil, "", 1,
|
|
229
|
-
# # => [
|
|
177
|
+
# Set.new([nil, "", 1, false]).compact_blank
|
|
178
|
+
# # => [1]
|
|
230
179
|
#
|
|
231
180
|
# When called on a +Hash+, returns a new +Hash+ without the blank values.
|
|
232
181
|
#
|
|
@@ -245,20 +194,32 @@ module Enumerable
|
|
|
245
194
|
# If the +series+ include keys that have no corresponding element in the Enumerable, these are ignored.
|
|
246
195
|
# If the Enumerable has additional elements that aren't named in the +series+, these are not included in the result.
|
|
247
196
|
def in_order_of(key, series)
|
|
248
|
-
|
|
197
|
+
group_by(&key).values_at(*series).flatten(1).compact
|
|
249
198
|
end
|
|
250
199
|
|
|
251
200
|
# Returns the sole item in the enumerable. If there are no items, or more
|
|
252
|
-
# than one item, raises
|
|
201
|
+
# than one item, raises Enumerable::SoleItemExpectedError.
|
|
253
202
|
#
|
|
254
203
|
# ["x"].sole # => "x"
|
|
255
204
|
# Set.new.sole # => Enumerable::SoleItemExpectedError: no item found
|
|
256
205
|
# { a: 1, b: 2 }.sole # => Enumerable::SoleItemExpectedError: multiple items found
|
|
257
206
|
def sole
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
207
|
+
result = nil
|
|
208
|
+
found = false
|
|
209
|
+
|
|
210
|
+
each do |*element|
|
|
211
|
+
if found
|
|
212
|
+
raise SoleItemExpectedError, "multiple items found"
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
result = element.size == 1 ? element[0] : element
|
|
216
|
+
found = true
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
if found
|
|
220
|
+
result
|
|
221
|
+
else
|
|
222
|
+
raise SoleItemExpectedError, "no item found"
|
|
262
223
|
end
|
|
263
224
|
end
|
|
264
225
|
end
|
|
@@ -284,38 +245,22 @@ end
|
|
|
284
245
|
class Range # :nodoc:
|
|
285
246
|
# Optimize range sum to use arithmetic progression if a block is not given and
|
|
286
247
|
# we have a range of numeric values.
|
|
287
|
-
def sum(
|
|
248
|
+
def sum(initial_value = 0)
|
|
288
249
|
if block_given? || !(first.is_a?(Integer) && last.is_a?(Integer))
|
|
289
250
|
super
|
|
290
251
|
else
|
|
291
252
|
actual_last = exclude_end? ? (last - 1) : last
|
|
292
253
|
if actual_last >= first
|
|
293
|
-
sum =
|
|
254
|
+
sum = initial_value || 0
|
|
294
255
|
sum + (actual_last - first + 1) * (actual_last + first) / 2
|
|
295
256
|
else
|
|
296
|
-
|
|
257
|
+
initial_value || 0
|
|
297
258
|
end
|
|
298
259
|
end
|
|
299
260
|
end
|
|
300
261
|
end
|
|
301
262
|
|
|
302
|
-
# Using Refinements here in order not to expose our internal method
|
|
303
|
-
using Module.new {
|
|
304
|
-
refine Array do
|
|
305
|
-
alias :orig_sum :sum
|
|
306
|
-
end
|
|
307
|
-
}
|
|
308
|
-
|
|
309
263
|
class Array # :nodoc:
|
|
310
|
-
def sum(init = nil, &block)
|
|
311
|
-
if init.is_a?(Numeric) || first.is_a?(Numeric)
|
|
312
|
-
init ||= 0
|
|
313
|
-
orig_sum(init, &block)
|
|
314
|
-
else
|
|
315
|
-
super
|
|
316
|
-
end
|
|
317
|
-
end
|
|
318
|
-
|
|
319
264
|
# Removes all blank elements from the +Array+ in place and returns self.
|
|
320
265
|
# Uses Object#blank? for determining if an item is blank.
|
|
321
266
|
#
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "erb"
|
|
4
|
+
|
|
5
|
+
module ActiveSupport
|
|
6
|
+
module CoreExt
|
|
7
|
+
module ERBUtil
|
|
8
|
+
# HTML escapes strings but doesn't wrap them with an ActiveSupport::SafeBuffer.
|
|
9
|
+
# This method is not for public consumption! Seriously!
|
|
10
|
+
def html_escape(s) # :nodoc:
|
|
11
|
+
s = s.to_s
|
|
12
|
+
if s.html_safe?
|
|
13
|
+
s
|
|
14
|
+
else
|
|
15
|
+
super(ActiveSupport::Multibyte::Unicode.tidy_bytes(s))
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
alias :unwrapped_html_escape :html_escape # :nodoc:
|
|
19
|
+
|
|
20
|
+
# A utility method for escaping HTML tag characters.
|
|
21
|
+
# This method is also aliased as <tt>h</tt>.
|
|
22
|
+
#
|
|
23
|
+
# puts html_escape('is a > 0 & a < 10?')
|
|
24
|
+
# # => is a > 0 & a < 10?
|
|
25
|
+
def html_escape(s) # rubocop:disable Lint/DuplicateMethods
|
|
26
|
+
unwrapped_html_escape(s).html_safe
|
|
27
|
+
end
|
|
28
|
+
alias h html_escape
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
module ERBUtilPrivate
|
|
32
|
+
include ERBUtil
|
|
33
|
+
private :unwrapped_html_escape, :html_escape, :h
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
class ERB
|
|
39
|
+
module Util
|
|
40
|
+
HTML_ESCAPE = { "&" => "&", ">" => ">", "<" => "<", '"' => """, "'" => "'" }
|
|
41
|
+
HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+)|(#[xX][\dA-Fa-f]+));)/
|
|
42
|
+
|
|
43
|
+
# Following XML requirements: https://www.w3.org/TR/REC-xml/#NT-Name
|
|
44
|
+
TAG_NAME_START_CODEPOINTS = "@:A-Z_a-z\u{C0}-\u{D6}\u{D8}-\u{F6}\u{F8}-\u{2FF}\u{370}-\u{37D}\u{37F}-\u{1FFF}" \
|
|
45
|
+
"\u{200C}-\u{200D}\u{2070}-\u{218F}\u{2C00}-\u{2FEF}\u{3001}-\u{D7FF}\u{F900}-\u{FDCF}" \
|
|
46
|
+
"\u{FDF0}-\u{FFFD}\u{10000}-\u{EFFFF}"
|
|
47
|
+
INVALID_TAG_NAME_START_REGEXP = /[^#{TAG_NAME_START_CODEPOINTS}]/
|
|
48
|
+
TAG_NAME_FOLLOWING_CODEPOINTS = "#{TAG_NAME_START_CODEPOINTS}\\-.0-9\u{B7}\u{0300}-\u{036F}\u{203F}-\u{2040}"
|
|
49
|
+
INVALID_TAG_NAME_FOLLOWING_REGEXP = /[^#{TAG_NAME_FOLLOWING_CODEPOINTS}]/
|
|
50
|
+
SAFE_XML_TAG_NAME_REGEXP = /\A[#{TAG_NAME_START_CODEPOINTS}][#{TAG_NAME_FOLLOWING_CODEPOINTS}]*\z/
|
|
51
|
+
TAG_NAME_REPLACEMENT_CHAR = "_"
|
|
52
|
+
|
|
53
|
+
prepend ActiveSupport::CoreExt::ERBUtilPrivate
|
|
54
|
+
singleton_class.prepend ActiveSupport::CoreExt::ERBUtil
|
|
55
|
+
|
|
56
|
+
# A utility method for escaping HTML without affecting existing escaped entities.
|
|
57
|
+
#
|
|
58
|
+
# html_escape_once('1 < 2 & 3')
|
|
59
|
+
# # => "1 < 2 & 3"
|
|
60
|
+
#
|
|
61
|
+
# html_escape_once('<< Accept & Checkout')
|
|
62
|
+
# # => "<< Accept & Checkout"
|
|
63
|
+
def html_escape_once(s)
|
|
64
|
+
ActiveSupport::Multibyte::Unicode.tidy_bytes(s.to_s).gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE).html_safe
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
module_function :html_escape_once
|
|
68
|
+
|
|
69
|
+
# A utility method for escaping HTML entities in JSON strings. Specifically, the
|
|
70
|
+
# &, > and < characters are replaced with their equivalent unicode escaped form -
|
|
71
|
+
# \u0026, \u003e, and \u003c. The Unicode sequences \u2028 and \u2029 are also
|
|
72
|
+
# escaped as they are treated as newline characters in some JavaScript engines.
|
|
73
|
+
# These sequences have identical meaning as the original characters inside the
|
|
74
|
+
# context of a JSON string, so assuming the input is a valid and well-formed
|
|
75
|
+
# JSON value, the output will have equivalent meaning when parsed:
|
|
76
|
+
#
|
|
77
|
+
# json = JSON.generate({ name: "</script><script>alert('PWNED!!!')</script>"})
|
|
78
|
+
# # => "{\"name\":\"</script><script>alert('PWNED!!!')</script>\"}"
|
|
79
|
+
#
|
|
80
|
+
# json_escape(json)
|
|
81
|
+
# # => "{\"name\":\"\\u003C/script\\u003E\\u003Cscript\\u003Ealert('PWNED!!!')\\u003C/script\\u003E\"}"
|
|
82
|
+
#
|
|
83
|
+
# JSON.parse(json) == JSON.parse(json_escape(json))
|
|
84
|
+
# # => true
|
|
85
|
+
#
|
|
86
|
+
# The intended use case for this method is to escape JSON strings before including
|
|
87
|
+
# them inside a script tag to avoid XSS vulnerability:
|
|
88
|
+
#
|
|
89
|
+
# <script>
|
|
90
|
+
# var currentUser = <%= raw json_escape(current_user.to_json) %>;
|
|
91
|
+
# </script>
|
|
92
|
+
#
|
|
93
|
+
# It is necessary to +raw+ the result of +json_escape+, so that quotation marks
|
|
94
|
+
# don't get converted to <tt>"</tt> entities. +json_escape+ doesn't
|
|
95
|
+
# automatically flag the result as HTML safe, since the raw value is unsafe to
|
|
96
|
+
# use inside HTML attributes.
|
|
97
|
+
#
|
|
98
|
+
# If your JSON is being used downstream for insertion into the DOM, be aware of
|
|
99
|
+
# whether or not it is being inserted via <tt>html()</tt>. Most jQuery plugins do this.
|
|
100
|
+
# If that is the case, be sure to +html_escape+ or +sanitize+ any user-generated
|
|
101
|
+
# content returned by your JSON.
|
|
102
|
+
#
|
|
103
|
+
# If you need to output JSON elsewhere in your HTML, you can just do something
|
|
104
|
+
# like this, as any unsafe characters (including quotation marks) will be
|
|
105
|
+
# automatically escaped for you:
|
|
106
|
+
#
|
|
107
|
+
# <div data-user-info="<%= current_user.to_json %>">...</div>
|
|
108
|
+
#
|
|
109
|
+
# WARNING: this helper only works with valid JSON. Using this on non-JSON values
|
|
110
|
+
# will open up serious XSS vulnerabilities. For example, if you replace the
|
|
111
|
+
# +current_user.to_json+ in the example above with user input instead, the browser
|
|
112
|
+
# will happily <tt>eval()</tt> that string as JavaScript.
|
|
113
|
+
#
|
|
114
|
+
# The escaping performed in this method is identical to those performed in the
|
|
115
|
+
# Active Support JSON encoder when +ActiveSupport.escape_html_entities_in_json+ is
|
|
116
|
+
# set to true. Because this transformation is idempotent, this helper can be
|
|
117
|
+
# applied even if +ActiveSupport.escape_html_entities_in_json+ is already true.
|
|
118
|
+
#
|
|
119
|
+
# Therefore, when you are unsure if +ActiveSupport.escape_html_entities_in_json+
|
|
120
|
+
# is enabled, or if you are unsure where your JSON string originated from, it
|
|
121
|
+
# is recommended that you always apply this helper (other libraries, such as the
|
|
122
|
+
# JSON gem, do not provide this kind of protection by default; also some gems
|
|
123
|
+
# might override +to_json+ to bypass Active Support's encoder).
|
|
124
|
+
def json_escape(s)
|
|
125
|
+
result = s.to_s.dup
|
|
126
|
+
result.gsub!(">", '\u003e')
|
|
127
|
+
result.gsub!("<", '\u003c')
|
|
128
|
+
result.gsub!("&", '\u0026')
|
|
129
|
+
result.gsub!("\u2028", '\u2028')
|
|
130
|
+
result.gsub!("\u2029", '\u2029')
|
|
131
|
+
s.html_safe? ? result.html_safe : result
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
module_function :json_escape
|
|
135
|
+
|
|
136
|
+
# A utility method for escaping XML names of tags and names of attributes.
|
|
137
|
+
#
|
|
138
|
+
# xml_name_escape('1 < 2 & 3')
|
|
139
|
+
# # => "1___2___3"
|
|
140
|
+
#
|
|
141
|
+
# It follows the requirements of the specification: https://www.w3.org/TR/REC-xml/#NT-Name
|
|
142
|
+
def xml_name_escape(name)
|
|
143
|
+
name = name.to_s
|
|
144
|
+
return "" if name.blank?
|
|
145
|
+
return name if name.match?(SAFE_XML_TAG_NAME_REGEXP)
|
|
146
|
+
|
|
147
|
+
starting_char = name[0]
|
|
148
|
+
starting_char.gsub!(INVALID_TAG_NAME_START_REGEXP, TAG_NAME_REPLACEMENT_CHAR)
|
|
149
|
+
|
|
150
|
+
return starting_char if name.size == 1
|
|
151
|
+
|
|
152
|
+
following_chars = name[1..-1]
|
|
153
|
+
following_chars.gsub!(INVALID_TAG_NAME_FOLLOWING_REGEXP, TAG_NAME_REPLACEMENT_CHAR)
|
|
154
|
+
|
|
155
|
+
starting_char << following_chars
|
|
156
|
+
end
|
|
157
|
+
module_function :xml_name_escape
|
|
158
|
+
|
|
159
|
+
# Tokenizes a line of ERB. This is really just for error reporting and
|
|
160
|
+
# nobody should use it.
|
|
161
|
+
def self.tokenize(source) # :nodoc:
|
|
162
|
+
require "strscan"
|
|
163
|
+
source = StringScanner.new(source.chomp)
|
|
164
|
+
tokens = []
|
|
165
|
+
|
|
166
|
+
start_re = /<%(?:={1,2}|-|\#|%)?/m
|
|
167
|
+
finish_re = /(?:[-=])?%>/m
|
|
168
|
+
|
|
169
|
+
while !source.eos?
|
|
170
|
+
pos = source.pos
|
|
171
|
+
source.scan_until(/(?:#{start_re}|#{finish_re})/)
|
|
172
|
+
raise NotImplementedError if source.matched.nil?
|
|
173
|
+
len = source.pos - source.matched.bytesize - pos
|
|
174
|
+
|
|
175
|
+
case source.matched
|
|
176
|
+
when start_re
|
|
177
|
+
tokens << [:TEXT, source.string.byteslice(pos, len)] if len > 0
|
|
178
|
+
tokens << [:OPEN, source.matched]
|
|
179
|
+
if source.scan(/(.*?)(?=#{finish_re}|\z)/m)
|
|
180
|
+
tokens << [:CODE, source.matched] unless source.matched.empty?
|
|
181
|
+
tokens << [:CLOSE, source.scan(finish_re)] unless source.eos?
|
|
182
|
+
else
|
|
183
|
+
raise NotImplementedError
|
|
184
|
+
end
|
|
185
|
+
when finish_re
|
|
186
|
+
tokens << [:CODE, source.string.byteslice(pos, len)] if len > 0
|
|
187
|
+
tokens << [:CLOSE, source.matched]
|
|
188
|
+
else
|
|
189
|
+
raise NotImplementedError, source.matched
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
unless source.eos? || source.exist?(start_re) || source.exist?(finish_re)
|
|
193
|
+
tokens << [:TEXT, source.rest]
|
|
194
|
+
source.terminate
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
tokens
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
@@ -68,7 +68,7 @@ class Hash
|
|
|
68
68
|
#
|
|
69
69
|
# By default the root node is "hash", but that's configurable via the <tt>:root</tt> option.
|
|
70
70
|
#
|
|
71
|
-
# The default XML builder is a fresh instance of
|
|
71
|
+
# The default XML builder is a fresh instance of +Builder::XmlMarkup+. You can
|
|
72
72
|
# configure your own builder with the <tt>:builder</tt> option. The method also accepts
|
|
73
73
|
# options like <tt>:dasherize</tt> and friends, they are forwarded to the builder.
|
|
74
74
|
def to_xml(options = {})
|