activesupport 6.0.0.beta3 → 6.0.0.rc1
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 +4 -4
- data/CHANGELOG.md +149 -1
- data/README.rdoc +2 -1
- data/lib/active_support.rb +1 -0
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +5 -1
- data/lib/active_support/cache.rb +5 -5
- data/lib/active_support/cache/redis_cache_store.rb +8 -5
- data/lib/active_support/concern.rb +24 -1
- data/lib/active_support/configurable.rb +3 -3
- data/lib/active_support/core_ext/array/access.rb +18 -6
- data/lib/active_support/core_ext/class/attribute.rb +10 -15
- data/lib/active_support/core_ext/enumerable.rb +24 -4
- data/lib/active_support/core_ext/hash/except.rb +1 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +5 -5
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +5 -5
- data/lib/active_support/core_ext/range/compare_range.rb +21 -12
- data/lib/active_support/core_ext/string/inflections.rb +7 -2
- data/lib/active_support/core_ext/string/output_safety.rb +49 -4
- data/lib/active_support/core_ext/time/calculations.rb +1 -2
- data/lib/active_support/dependencies.rb +5 -0
- data/lib/active_support/dependencies/zeitwerk_integration.rb +22 -18
- data/lib/active_support/deprecation/method_wrappers.rb +7 -18
- data/lib/active_support/descendants_tracker.rb +52 -6
- data/lib/active_support/duration.rb +0 -1
- data/lib/active_support/evented_file_update_checker.rb +3 -1
- data/lib/active_support/gem_version.rb +1 -1
- data/lib/active_support/hash_with_indifferent_access.rb +6 -3
- data/lib/active_support/i18n_railtie.rb +2 -1
- data/lib/active_support/inflector/transliterate.rb +16 -13
- data/lib/active_support/notifications/fanout.rb +4 -4
- data/lib/active_support/notifications/instrumenter.rb +8 -8
- data/lib/active_support/security_utils.rb +1 -1
- data/lib/active_support/subscriber.rb +55 -6
- data/lib/active_support/testing/parallelization.rb +13 -2
- metadata +10 -9
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "weakref"
|
4
|
+
|
3
5
|
module ActiveSupport
|
4
6
|
# This module provides an internal implementation to track descendants
|
5
7
|
# which is faster than iterating through ObjectSpace.
|
@@ -8,7 +10,8 @@ module ActiveSupport
|
|
8
10
|
|
9
11
|
class << self
|
10
12
|
def direct_descendants(klass)
|
11
|
-
@@direct_descendants[klass]
|
13
|
+
descendants = @@direct_descendants[klass]
|
14
|
+
descendants ? descendants.to_a : []
|
12
15
|
end
|
13
16
|
|
14
17
|
def descendants(klass)
|
@@ -20,10 +23,10 @@ module ActiveSupport
|
|
20
23
|
def clear
|
21
24
|
if defined? ActiveSupport::Dependencies
|
22
25
|
@@direct_descendants.each do |klass, descendants|
|
23
|
-
if
|
26
|
+
if Dependencies.autoloaded?(klass)
|
24
27
|
@@direct_descendants.delete(klass)
|
25
28
|
else
|
26
|
-
descendants.reject! { |v|
|
29
|
+
descendants.reject! { |v| Dependencies.autoloaded?(v) }
|
27
30
|
end
|
28
31
|
end
|
29
32
|
else
|
@@ -34,15 +37,17 @@ module ActiveSupport
|
|
34
37
|
# This is the only method that is not thread safe, but is only ever called
|
35
38
|
# during the eager loading phase.
|
36
39
|
def store_inherited(klass, descendant)
|
37
|
-
(@@direct_descendants[klass] ||=
|
40
|
+
(@@direct_descendants[klass] ||= DescendantsArray.new) << descendant
|
38
41
|
end
|
39
42
|
|
40
43
|
private
|
41
44
|
|
42
45
|
def accumulate_descendants(klass, acc)
|
43
46
|
if direct_descendants = @@direct_descendants[klass]
|
44
|
-
|
45
|
-
|
47
|
+
direct_descendants.each do |direct_descendant|
|
48
|
+
acc << direct_descendant
|
49
|
+
accumulate_descendants(direct_descendant, acc)
|
50
|
+
end
|
46
51
|
end
|
47
52
|
end
|
48
53
|
end
|
@@ -59,5 +64,46 @@ module ActiveSupport
|
|
59
64
|
def descendants
|
60
65
|
DescendantsTracker.descendants(self)
|
61
66
|
end
|
67
|
+
|
68
|
+
# DescendantsArray is an array that contains weak references to classes.
|
69
|
+
class DescendantsArray # :nodoc:
|
70
|
+
include Enumerable
|
71
|
+
|
72
|
+
def initialize
|
73
|
+
@refs = []
|
74
|
+
end
|
75
|
+
|
76
|
+
def initialize_copy(orig)
|
77
|
+
@refs = @refs.dup
|
78
|
+
end
|
79
|
+
|
80
|
+
def <<(klass)
|
81
|
+
cleanup!
|
82
|
+
@refs << WeakRef.new(klass)
|
83
|
+
end
|
84
|
+
|
85
|
+
def each
|
86
|
+
@refs.each do |ref|
|
87
|
+
yield ref.__getobj__
|
88
|
+
rescue WeakRef::RefError
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def refs_size
|
93
|
+
@refs.size
|
94
|
+
end
|
95
|
+
|
96
|
+
def cleanup!
|
97
|
+
@refs.delete_if { |ref| !ref.weakref_alive? }
|
98
|
+
end
|
99
|
+
|
100
|
+
def reject!
|
101
|
+
@refs.reject! do |ref|
|
102
|
+
yield ref.__getobj__
|
103
|
+
rescue WeakRef::RefError
|
104
|
+
true
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
62
108
|
end
|
63
109
|
end
|
@@ -4,7 +4,6 @@ require "active_support/core_ext/array/conversions"
|
|
4
4
|
require "active_support/core_ext/module/delegation"
|
5
5
|
require "active_support/core_ext/object/acts_like"
|
6
6
|
require "active_support/core_ext/string/filters"
|
7
|
-
require "active_support/deprecation"
|
8
7
|
|
9
8
|
module ActiveSupport
|
10
9
|
# Provides accurate date and time measurements using Date#advance and
|
@@ -131,7 +131,9 @@ module ActiveSupport
|
|
131
131
|
ext = @ph.normalize_extension(file.extname)
|
132
132
|
|
133
133
|
file.dirname.ascend do |dir|
|
134
|
-
|
134
|
+
matching = @dirs[dir]
|
135
|
+
|
136
|
+
if matching && (matching.empty? || matching.include?(ext))
|
135
137
|
break true
|
136
138
|
elsif dir == @lcsp || dir.root?
|
137
139
|
break false
|
@@ -225,8 +225,8 @@ module ActiveSupport
|
|
225
225
|
# hash[:a] = 'x'
|
226
226
|
# hash[:b] = 'y'
|
227
227
|
# hash.values_at('a', 'b') # => ["x", "y"]
|
228
|
-
def values_at(*
|
229
|
-
|
228
|
+
def values_at(*keys)
|
229
|
+
super(*keys.map { |key| convert_key(key) })
|
230
230
|
end
|
231
231
|
|
232
232
|
# Returns an array of the values at the specified indices, but also
|
@@ -239,7 +239,7 @@ module ActiveSupport
|
|
239
239
|
# hash.fetch_values('a', 'c') { |key| 'z' } # => ["x", "z"]
|
240
240
|
# hash.fetch_values('a', 'c') # => KeyError: key not found: "c"
|
241
241
|
def fetch_values(*indices, &block)
|
242
|
-
indices.
|
242
|
+
super(*indices.map { |key| convert_key(key) }, &block)
|
243
243
|
end
|
244
244
|
|
245
245
|
# Returns a shallow copy of the hash.
|
@@ -293,6 +293,9 @@ module ActiveSupport
|
|
293
293
|
super(convert_key(key))
|
294
294
|
end
|
295
295
|
|
296
|
+
def except(*keys)
|
297
|
+
slice(*self.keys - keys.map { |key| convert_key(key) })
|
298
|
+
end
|
296
299
|
alias_method :without, :except
|
297
300
|
|
298
301
|
def stringify_keys!; self end
|
@@ -97,7 +97,8 @@ module I18n
|
|
97
97
|
If you desire the default locale to be included in the defaults, please
|
98
98
|
explicitly configure it with `config.i18n.fallbacks.defaults =
|
99
99
|
[I18n.default_locale]` or `config.i18n.fallbacks = [I18n.default_locale,
|
100
|
-
{...}]
|
100
|
+
{...}]`. If you want to opt-in to the new behavior, use
|
101
|
+
`config.i18n.fallbacks.defaults = [nil, {...}]`.
|
101
102
|
MSG
|
102
103
|
args.unshift I18n.default_locale
|
103
104
|
end
|
@@ -51,19 +51,18 @@ module ActiveSupport
|
|
51
51
|
#
|
52
52
|
# Now you can have different transliterations for each locale:
|
53
53
|
#
|
54
|
-
#
|
55
|
-
# transliterate('Jürgen')
|
54
|
+
# transliterate('Jürgen', locale: :en)
|
56
55
|
# # => "Jurgen"
|
57
56
|
#
|
58
|
-
#
|
59
|
-
# transliterate('Jürgen')
|
57
|
+
# transliterate('Jürgen', locale: :de)
|
60
58
|
# # => "Juergen"
|
61
|
-
def transliterate(string, replacement = "?")
|
59
|
+
def transliterate(string, replacement = "?", locale: nil)
|
62
60
|
raise ArgumentError, "Can only transliterate strings. Received #{string.class.name}" unless string.is_a?(String)
|
63
61
|
|
64
62
|
I18n.transliterate(
|
65
63
|
ActiveSupport::Multibyte::Unicode.tidy_bytes(string).unicode_normalize(:nfc),
|
66
|
-
replacement: replacement
|
64
|
+
replacement: replacement,
|
65
|
+
locale: locale
|
67
66
|
)
|
68
67
|
end
|
69
68
|
|
@@ -75,8 +74,8 @@ module ActiveSupport
|
|
75
74
|
#
|
76
75
|
# To use a custom separator, override the +separator+ argument.
|
77
76
|
#
|
78
|
-
#
|
79
|
-
#
|
77
|
+
# parameterize("Donald E. Knuth", separator: '_') # => "donald_e_knuth"
|
78
|
+
# parameterize("^très|Jolie__ ", separator: '_') # => "tres_jolie"
|
80
79
|
#
|
81
80
|
# To preserve the case of the characters in a string, use the +preserve_case+ argument.
|
82
81
|
#
|
@@ -85,13 +84,17 @@ module ActiveSupport
|
|
85
84
|
#
|
86
85
|
# It preserves dashes and underscores unless they are used as separators:
|
87
86
|
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
87
|
+
# parameterize("^très|Jolie__ ") # => "tres-jolie__"
|
88
|
+
# parameterize("^très|Jolie-- ", separator: "_") # => "tres_jolie--"
|
89
|
+
# parameterize("^très_Jolie-- ", separator: ".") # => "tres_jolie--"
|
91
90
|
#
|
92
|
-
|
91
|
+
# If the optional parameter +locale+ is specified,
|
92
|
+
# the word will be parameterized as a word of that language.
|
93
|
+
# By default, this parameter is set to <tt>nil</tt> and it will use
|
94
|
+
# the configured <tt>I18n.locale<tt>.
|
95
|
+
def parameterize(string, separator: "-", preserve_case: false, locale: nil)
|
93
96
|
# Replace accented chars with their ASCII equivalents.
|
94
|
-
parameterized_string = transliterate(string)
|
97
|
+
parameterized_string = transliterate(string, locale: locale)
|
95
98
|
|
96
99
|
# Turn unwanted chars into the separator.
|
97
100
|
parameterized_string.gsub!(/[^a-z0-9\-_]+/i, separator)
|
@@ -20,8 +20,8 @@ module ActiveSupport
|
|
20
20
|
super
|
21
21
|
end
|
22
22
|
|
23
|
-
def subscribe(pattern = nil,
|
24
|
-
subscriber = Subscribers.new
|
23
|
+
def subscribe(pattern = nil, callable = nil, &block)
|
24
|
+
subscriber = Subscribers.new(pattern, callable || block)
|
25
25
|
synchronize do
|
26
26
|
if String === pattern
|
27
27
|
@string_subscribers[pattern] << subscriber
|
@@ -180,13 +180,13 @@ module ActiveSupport
|
|
180
180
|
|
181
181
|
def start(name, id, payload)
|
182
182
|
timestack = Thread.current[:_timestack] ||= []
|
183
|
-
timestack.push
|
183
|
+
timestack.push Concurrent.monotonic_time
|
184
184
|
end
|
185
185
|
|
186
186
|
def finish(name, id, payload)
|
187
187
|
timestack = Thread.current[:_timestack]
|
188
188
|
started = timestack.pop
|
189
|
-
@delegate.call(name, started,
|
189
|
+
@delegate.call(name, started, Concurrent.monotonic_time, id, payload)
|
190
190
|
end
|
191
191
|
end
|
192
192
|
|
@@ -13,14 +13,15 @@ module ActiveSupport
|
|
13
13
|
@notifier = notifier
|
14
14
|
end
|
15
15
|
|
16
|
-
#
|
17
|
-
# and publish it.
|
18
|
-
#
|
16
|
+
# Given a block, instrument it by measuring the time taken to execute
|
17
|
+
# and publish it. Without a block, simply send a message via the
|
18
|
+
# notifier. Notice that events get sent even if an error occurs in the
|
19
|
+
# passed-in block.
|
19
20
|
def instrument(name, payload = {})
|
20
21
|
# some of the listeners might have state
|
21
22
|
listeners_state = start name, payload
|
22
23
|
begin
|
23
|
-
yield payload
|
24
|
+
yield payload if block_given?
|
24
25
|
rescue Exception => e
|
25
26
|
payload[:exception] = [e.class.name, e.message]
|
26
27
|
payload[:exception_object] = e
|
@@ -67,9 +68,8 @@ module ActiveSupport
|
|
67
68
|
@transaction_id = transaction_id
|
68
69
|
@end = ending
|
69
70
|
@children = []
|
70
|
-
@
|
71
|
-
@
|
72
|
-
@cpu_time_finish = nil
|
71
|
+
@cpu_time_start = 0
|
72
|
+
@cpu_time_finish = 0
|
73
73
|
@allocation_count_start = 0
|
74
74
|
@allocation_count_finish = 0
|
75
75
|
end
|
@@ -124,7 +124,7 @@ module ActiveSupport
|
|
124
124
|
#
|
125
125
|
# @event.duration # => 1000.138
|
126
126
|
def duration
|
127
|
-
|
127
|
+
1000.0 * (self.end - time)
|
128
128
|
end
|
129
129
|
|
130
130
|
def <<(event)
|
@@ -24,7 +24,7 @@ module ActiveSupport
|
|
24
24
|
# The values are first processed by SHA256, so that we don't leak length info
|
25
25
|
# via timing attacks.
|
26
26
|
def secure_compare(a, b)
|
27
|
-
fixed_length_secure_compare(::Digest::SHA256.
|
27
|
+
fixed_length_secure_compare(::Digest::SHA256.digest(a), ::Digest::SHA256.digest(b)) && a == b
|
28
28
|
end
|
29
29
|
module_function :secure_compare
|
30
30
|
end
|
@@ -24,6 +24,10 @@ module ActiveSupport
|
|
24
24
|
# After configured, whenever a "sql.active_record" notification is published,
|
25
25
|
# it will properly dispatch the event (ActiveSupport::Notifications::Event) to
|
26
26
|
# the +sql+ method.
|
27
|
+
#
|
28
|
+
# We can detach a subscriber as well:
|
29
|
+
#
|
30
|
+
# ActiveRecord::StatsSubscriber.detach_from(:active_record)
|
27
31
|
class Subscriber
|
28
32
|
class << self
|
29
33
|
# Attach the subscriber to a namespace.
|
@@ -40,6 +44,25 @@ module ActiveSupport
|
|
40
44
|
end
|
41
45
|
end
|
42
46
|
|
47
|
+
# Detach the subscriber from a namespace.
|
48
|
+
def detach_from(namespace, notifier = ActiveSupport::Notifications)
|
49
|
+
@namespace = namespace
|
50
|
+
@subscriber = find_attached_subscriber
|
51
|
+
@notifier = notifier
|
52
|
+
|
53
|
+
return unless subscriber
|
54
|
+
|
55
|
+
subscribers.delete(subscriber)
|
56
|
+
|
57
|
+
# Remove event subscribers of all existing methods on the class.
|
58
|
+
subscriber.public_methods(false).each do |event|
|
59
|
+
remove_event_subscriber(event)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Reset notifier so that event subscribers will not add for new methods added to the class.
|
63
|
+
@notifier = nil
|
64
|
+
end
|
65
|
+
|
43
66
|
# Adds event subscribers for all new methods added to the class.
|
44
67
|
def method_added(event)
|
45
68
|
# Only public methods are added as subscribers, and only if a notifier
|
@@ -58,15 +81,41 @@ module ActiveSupport
|
|
58
81
|
attr_reader :subscriber, :notifier, :namespace
|
59
82
|
|
60
83
|
def add_event_subscriber(event) # :doc:
|
61
|
-
return if
|
84
|
+
return if invalid_event?(event.to_s)
|
62
85
|
|
63
|
-
pattern =
|
86
|
+
pattern = prepare_pattern(event)
|
64
87
|
|
65
88
|
# Don't add multiple subscribers (eg. if methods are redefined).
|
66
|
-
return if
|
89
|
+
return if pattern_subscribed?(pattern)
|
90
|
+
|
91
|
+
subscriber.patterns[pattern] = notifier.subscribe(pattern, subscriber)
|
92
|
+
end
|
93
|
+
|
94
|
+
def remove_event_subscriber(event) # :doc:
|
95
|
+
return if invalid_event?(event.to_s)
|
96
|
+
|
97
|
+
pattern = prepare_pattern(event)
|
98
|
+
|
99
|
+
return unless pattern_subscribed?(pattern)
|
100
|
+
|
101
|
+
notifier.unsubscribe(subscriber.patterns[pattern])
|
102
|
+
subscriber.patterns.delete(pattern)
|
103
|
+
end
|
104
|
+
|
105
|
+
def find_attached_subscriber
|
106
|
+
subscribers.find { |attached_subscriber| attached_subscriber.instance_of?(self) }
|
107
|
+
end
|
108
|
+
|
109
|
+
def invalid_event?(event)
|
110
|
+
%w{ start finish }.include?(event.to_s)
|
111
|
+
end
|
112
|
+
|
113
|
+
def prepare_pattern(event)
|
114
|
+
"#{event}.#{namespace}"
|
115
|
+
end
|
67
116
|
|
68
|
-
|
69
|
-
|
117
|
+
def pattern_subscribed?(pattern)
|
118
|
+
subscriber.patterns.key?(pattern)
|
70
119
|
end
|
71
120
|
end
|
72
121
|
|
@@ -74,7 +123,7 @@ module ActiveSupport
|
|
74
123
|
|
75
124
|
def initialize
|
76
125
|
@queue_key = [self.class.name, object_id].join "-"
|
77
|
-
@patterns =
|
126
|
+
@patterns = {}
|
78
127
|
super
|
79
128
|
end
|
80
129
|
|
@@ -71,7 +71,9 @@ module ActiveSupport
|
|
71
71
|
fork do
|
72
72
|
DRb.stop_service
|
73
73
|
|
74
|
-
|
74
|
+
begin
|
75
|
+
after_fork(worker)
|
76
|
+
rescue => setup_exception; end
|
75
77
|
|
76
78
|
queue = DRbObject.new_with_uri(@url)
|
77
79
|
|
@@ -79,7 +81,11 @@ module ActiveSupport
|
|
79
81
|
klass = job[0]
|
80
82
|
method = job[1]
|
81
83
|
reporter = job[2]
|
82
|
-
result
|
84
|
+
result = klass.with_info_handler reporter do
|
85
|
+
Minitest.run_one_method(klass, method)
|
86
|
+
end
|
87
|
+
|
88
|
+
add_setup_exception(result, setup_exception) if setup_exception
|
83
89
|
|
84
90
|
begin
|
85
91
|
queue.record(reporter, result)
|
@@ -104,6 +110,11 @@ module ActiveSupport
|
|
104
110
|
@queue_size.times { @queue << nil }
|
105
111
|
@pool.each { |pid| Process.waitpid pid }
|
106
112
|
end
|
113
|
+
|
114
|
+
private
|
115
|
+
def add_setup_exception(result, setup_exception)
|
116
|
+
result.failures.prepend Minitest::UnexpectedError.new(setup_exception)
|
117
|
+
end
|
107
118
|
end
|
108
119
|
end
|
109
120
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activesupport
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.0.0.
|
4
|
+
version: 6.0.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-04-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: i18n
|
@@ -84,20 +84,20 @@ dependencies:
|
|
84
84
|
requirements:
|
85
85
|
- - "~>"
|
86
86
|
- !ruby/object:Gem::Version
|
87
|
-
version: '1
|
87
|
+
version: '2.1'
|
88
88
|
- - ">="
|
89
89
|
- !ruby/object:Gem::Version
|
90
|
-
version: 1.
|
90
|
+
version: 2.1.4
|
91
91
|
type: :runtime
|
92
92
|
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
95
|
- - "~>"
|
96
96
|
- !ruby/object:Gem::Version
|
97
|
-
version: '1
|
97
|
+
version: '2.1'
|
98
98
|
- - ">="
|
99
99
|
- !ruby/object:Gem::Version
|
100
|
-
version: 1.
|
100
|
+
version: 2.1.4
|
101
101
|
description: A toolkit of support libraries and Ruby core extensions extracted from
|
102
102
|
the Rails framework. Rich support for multibyte strings, internationalization, time
|
103
103
|
zones, and testing.
|
@@ -110,6 +110,7 @@ files:
|
|
110
110
|
- MIT-LICENSE
|
111
111
|
- README.rdoc
|
112
112
|
- lib/active_support.rb
|
113
|
+
- lib/active_support/actionable_error.rb
|
113
114
|
- lib/active_support/all.rb
|
114
115
|
- lib/active_support/array_inquirer.rb
|
115
116
|
- lib/active_support/backtrace_cleaner.rb
|
@@ -352,12 +353,12 @@ files:
|
|
352
353
|
- lib/active_support/xml_mini/nokogiri.rb
|
353
354
|
- lib/active_support/xml_mini/nokogirisax.rb
|
354
355
|
- lib/active_support/xml_mini/rexml.rb
|
355
|
-
homepage:
|
356
|
+
homepage: https://rubyonrails.org
|
356
357
|
licenses:
|
357
358
|
- MIT
|
358
359
|
metadata:
|
359
|
-
source_code_uri: https://github.com/rails/rails/tree/v6.0.0.
|
360
|
-
changelog_uri: https://github.com/rails/rails/blob/v6.0.0.
|
360
|
+
source_code_uri: https://github.com/rails/rails/tree/v6.0.0.rc1/activesupport
|
361
|
+
changelog_uri: https://github.com/rails/rails/blob/v6.0.0.rc1/activesupport/CHANGELOG.md
|
361
362
|
post_install_message:
|
362
363
|
rdoc_options:
|
363
364
|
- "--encoding"
|