activesupport 4.2.11.3 → 5.0.0.beta1
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 +5 -5
- data/CHANGELOG.md +309 -485
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -3
- data/lib/active_support.rb +8 -15
- data/lib/active_support/array_inquirer.rb +44 -0
- data/lib/active_support/backtrace_cleaner.rb +1 -1
- data/lib/active_support/cache.rb +59 -72
- data/lib/active_support/cache/file_store.rb +27 -19
- data/lib/active_support/cache/mem_cache_store.rb +71 -60
- data/lib/active_support/cache/memory_store.rb +16 -21
- data/lib/active_support/cache/null_store.rb +1 -4
- data/lib/active_support/cache/strategy/local_cache.rb +31 -20
- data/lib/active_support/callbacks.rb +107 -111
- data/lib/active_support/concern.rb +1 -1
- data/lib/active_support/concurrency/latch.rb +7 -15
- data/lib/active_support/concurrency/share_lock.rb +142 -0
- data/lib/active_support/configurable.rb +1 -0
- data/lib/active_support/core_ext.rb +2 -1
- data/lib/active_support/core_ext/array.rb +1 -0
- data/lib/active_support/core_ext/array/access.rb +13 -1
- data/lib/active_support/core_ext/array/conversions.rb +6 -4
- data/lib/active_support/core_ext/array/inquiry.rb +17 -0
- data/lib/active_support/core_ext/array/wrap.rb +5 -4
- data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -10
- data/lib/active_support/core_ext/class.rb +0 -1
- data/lib/active_support/core_ext/class/attribute.rb +10 -9
- data/lib/active_support/core_ext/class/subclasses.rb +5 -2
- data/lib/active_support/core_ext/date.rb +1 -1
- data/lib/active_support/core_ext/date/blank.rb +12 -0
- data/lib/active_support/core_ext/date/calculations.rb +1 -1
- data/lib/active_support/core_ext/date/conversions.rb +3 -3
- data/lib/active_support/core_ext/date_and_time/calculations.rb +93 -27
- data/lib/active_support/core_ext/date_and_time/zones.rb +1 -2
- data/lib/active_support/core_ext/date_time.rb +1 -1
- data/lib/active_support/core_ext/date_time/blank.rb +12 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +7 -23
- data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
- data/lib/active_support/core_ext/enumerable.rb +27 -17
- data/lib/active_support/core_ext/file/atomic.rb +30 -25
- data/lib/active_support/core_ext/hash/compact.rb +15 -19
- data/lib/active_support/core_ext/hash/conversions.rb +21 -2
- data/lib/active_support/core_ext/hash/deep_merge.rb +1 -1
- data/lib/active_support/core_ext/hash/except.rb +9 -8
- data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +22 -18
- data/lib/active_support/core_ext/hash/slice.rb +1 -1
- data/lib/active_support/core_ext/hash/transform_values.rb +13 -7
- data/lib/active_support/core_ext/integer/time.rb +1 -1
- data/lib/active_support/core_ext/kernel.rb +0 -1
- data/lib/active_support/core_ext/kernel/debugger.rb +3 -10
- data/lib/active_support/core_ext/kernel/reporting.rb +0 -84
- data/lib/active_support/core_ext/load_error.rb +4 -2
- data/lib/active_support/core_ext/marshal.rb +8 -13
- data/lib/active_support/core_ext/module.rb +1 -0
- data/lib/active_support/core_ext/module/aliasing.rb +6 -1
- data/lib/active_support/core_ext/module/anonymous.rb +10 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
- data/lib/active_support/core_ext/module/attribute_accessors.rb +7 -7
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
- data/lib/active_support/core_ext/module/concerning.rb +4 -4
- data/lib/active_support/core_ext/module/delegation.rb +7 -14
- data/lib/active_support/core_ext/module/method_transplanting.rb +3 -13
- data/lib/active_support/core_ext/module/qualified_const.rb +30 -12
- data/lib/active_support/core_ext/module/remove_method.rb +23 -0
- data/lib/active_support/core_ext/name_error.rb +15 -2
- data/lib/active_support/core_ext/numeric.rb +1 -0
- data/lib/active_support/core_ext/numeric/bytes.rb +20 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +12 -23
- data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
- data/lib/active_support/core_ext/numeric/time.rb +20 -0
- data/lib/active_support/core_ext/object.rb +0 -1
- data/lib/active_support/core_ext/object/blank.rb +11 -2
- data/lib/active_support/core_ext/object/deep_dup.rb +10 -3
- data/lib/active_support/core_ext/object/duplicable.rb +39 -70
- data/lib/active_support/core_ext/object/inclusion.rb +2 -2
- data/lib/active_support/core_ext/object/instance_variables.rb +1 -1
- data/lib/active_support/core_ext/object/json.rb +9 -7
- data/lib/active_support/core_ext/object/to_query.rb +1 -1
- data/lib/active_support/core_ext/object/try.rb +67 -21
- data/lib/active_support/core_ext/object/with_options.rb +1 -1
- data/lib/active_support/core_ext/range/conversions.rb +18 -6
- data/lib/active_support/core_ext/range/each.rb +16 -18
- data/lib/active_support/core_ext/range/include_range.rb +20 -20
- data/lib/active_support/core_ext/securerandom.rb +23 -0
- data/lib/active_support/core_ext/string/access.rb +1 -1
- data/lib/active_support/core_ext/string/behavior.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +2 -2
- data/lib/active_support/core_ext/string/filters.rb +1 -2
- data/lib/active_support/core_ext/string/inflections.rb +23 -5
- data/lib/active_support/core_ext/string/multibyte.rb +11 -7
- data/lib/active_support/core_ext/string/output_safety.rb +8 -9
- data/lib/active_support/core_ext/string/strip.rb +3 -6
- data/lib/active_support/core_ext/struct.rb +3 -6
- data/lib/active_support/core_ext/time.rb +0 -2
- data/lib/active_support/core_ext/time/calculations.rb +18 -16
- data/lib/active_support/core_ext/time/conversions.rb +4 -2
- data/lib/active_support/core_ext/time/marshal.rb +2 -29
- data/lib/active_support/core_ext/time/zones.rb +19 -3
- data/lib/active_support/core_ext/uri.rb +1 -3
- data/lib/active_support/dependencies.rb +79 -44
- data/lib/active_support/dependencies/interlock.rb +47 -0
- data/lib/active_support/deprecation/behaviors.rb +12 -0
- data/lib/active_support/deprecation/method_wrappers.rb +42 -16
- data/lib/active_support/deprecation/proxy_wrappers.rb +47 -24
- data/lib/active_support/deprecation/reporting.rb +13 -2
- data/lib/active_support/duration.rb +5 -8
- data/lib/active_support/evented_file_update_checker.rb +150 -0
- data/lib/active_support/file_update_checker.rb +1 -1
- data/lib/active_support/gem_version.rb +5 -5
- data/lib/active_support/hash_with_indifferent_access.rb +15 -17
- data/lib/active_support/i18n_railtie.rb +25 -4
- data/lib/active_support/inflector/inflections.rb +36 -5
- data/lib/active_support/inflector/methods.rb +87 -89
- data/lib/active_support/inflector/transliterate.rb +36 -21
- data/lib/active_support/json/decoding.rb +2 -8
- data/lib/active_support/json/encoding.rb +0 -50
- data/lib/active_support/key_generator.rb +4 -4
- data/lib/active_support/log_subscriber.rb +1 -1
- data/lib/active_support/log_subscriber/test_helper.rb +3 -3
- data/lib/active_support/logger.rb +4 -52
- data/lib/active_support/logger_silence.rb +3 -5
- data/lib/active_support/message_encryptor.rb +4 -11
- data/lib/active_support/message_verifier.rb +64 -8
- data/lib/active_support/multibyte/chars.rb +12 -3
- data/lib/active_support/multibyte/unicode.rb +6 -8
- data/lib/active_support/notifications.rb +2 -2
- data/lib/active_support/notifications/fanout.rb +5 -5
- data/lib/active_support/notifications/instrumenter.rb +19 -2
- data/lib/active_support/number_helper.rb +21 -15
- data/lib/active_support/number_helper/number_to_currency_converter.rb +4 -4
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +7 -2
- data/lib/active_support/number_helper/number_to_human_converter.rb +6 -4
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +5 -1
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +28 -25
- data/lib/active_support/ordered_options.rb +15 -1
- data/lib/active_support/per_thread_registry.rb +3 -0
- data/lib/active_support/rails.rb +2 -2
- data/lib/active_support/railtie.rb +6 -1
- data/lib/active_support/rescuable.rb +4 -4
- data/lib/active_support/security_utils.rb +0 -7
- data/lib/active_support/string_inquirer.rb +1 -1
- data/lib/active_support/subscriber.rb +5 -10
- data/lib/active_support/tagged_logging.rb +3 -1
- data/lib/active_support/test_case.rb +13 -25
- data/lib/active_support/testing/assertions.rb +15 -13
- data/lib/active_support/testing/autorun.rb +8 -1
- data/lib/active_support/testing/composite_filter.rb +54 -0
- data/lib/active_support/testing/deprecation.rb +9 -8
- data/lib/active_support/testing/file_fixtures.rb +34 -0
- data/lib/active_support/testing/isolation.rb +22 -8
- data/lib/active_support/testing/method_call_assertions.rb +41 -0
- data/lib/active_support/testing/stream.rb +42 -0
- data/lib/active_support/testing/time_helpers.rb +6 -6
- data/lib/active_support/time_with_zone.rb +135 -53
- data/lib/active_support/values/time_zone.rb +80 -46
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/xml_mini.rb +15 -30
- data/lib/active_support/xml_mini/jdom.rb +1 -1
- data/lib/active_support/xml_mini/libxml.rb +5 -3
- data/lib/active_support/xml_mini/libxmlsax.rb +4 -1
- data/lib/active_support/xml_mini/nokogiri.rb +5 -3
- data/lib/active_support/xml_mini/nokogirisax.rb +3 -1
- data/lib/active_support/xml_mini/rexml.rb +3 -1
- metadata +57 -21
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +0 -15
- data/lib/active_support/core_ext/date_time/compatibility.rb +0 -16
- data/lib/active_support/core_ext/object/itself.rb +0 -15
- data/lib/active_support/core_ext/thread.rb +0 -86
- data/lib/active_support/core_ext/time/compatibility.rb +0 -14
- data/lib/active_support/logger_thread_safe_level.rb +0 -32
@@ -114,7 +114,7 @@ module ActiveSupport
|
|
114
114
|
return false
|
115
115
|
else
|
116
116
|
return false if base < self
|
117
|
-
@_dependencies.each { |dep| base.
|
117
|
+
@_dependencies.each { |dep| base.include(dep) }
|
118
118
|
super
|
119
119
|
base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods)
|
120
120
|
base.class_eval(&@_included_block) if instance_variable_defined?(:@_included_block)
|
@@ -1,26 +1,18 @@
|
|
1
|
-
require '
|
2
|
-
require 'monitor'
|
1
|
+
require 'concurrent/atomic/count_down_latch'
|
3
2
|
|
4
3
|
module ActiveSupport
|
5
4
|
module Concurrency
|
6
|
-
class Latch
|
5
|
+
class Latch < Concurrent::CountDownLatch
|
6
|
+
|
7
7
|
def initialize(count = 1)
|
8
|
-
|
9
|
-
|
10
|
-
@cv = @lock.new_cond
|
8
|
+
ActiveSupport::Deprecation.warn("ActiveSupport::Concurrency::Latch is deprecated. Please use Concurrent::CountDownLatch instead.")
|
9
|
+
super(count)
|
11
10
|
end
|
12
11
|
|
13
|
-
|
14
|
-
@lock.synchronize do
|
15
|
-
@count -= 1 if @count > 0
|
16
|
-
@cv.broadcast if @count.zero?
|
17
|
-
end
|
18
|
-
end
|
12
|
+
alias_method :release, :count_down
|
19
13
|
|
20
14
|
def await
|
21
|
-
|
22
|
-
@cv.wait_while { @count > 0 }
|
23
|
-
end
|
15
|
+
wait(nil)
|
24
16
|
end
|
25
17
|
end
|
26
18
|
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'thread'
|
2
|
+
require 'monitor'
|
3
|
+
|
4
|
+
module ActiveSupport
|
5
|
+
module Concurrency
|
6
|
+
# A share/exclusive lock, otherwise known as a read/write lock.
|
7
|
+
#
|
8
|
+
# https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock
|
9
|
+
#--
|
10
|
+
# Note that a pending Exclusive lock attempt does not block incoming
|
11
|
+
# Share requests (i.e., we are "read-preferring"). That seems
|
12
|
+
# consistent with the behavior of "loose" upgrades, but may be the
|
13
|
+
# wrong choice otherwise: it nominally reduces the possibility of
|
14
|
+
# deadlock by risking starvation instead.
|
15
|
+
class ShareLock
|
16
|
+
include MonitorMixin
|
17
|
+
|
18
|
+
# We track Thread objects, instead of just using counters, because
|
19
|
+
# we need exclusive locks to be reentrant, and we need to be able
|
20
|
+
# to upgrade share locks to exclusive.
|
21
|
+
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
super()
|
25
|
+
|
26
|
+
@cv = new_cond
|
27
|
+
|
28
|
+
@sharing = Hash.new(0)
|
29
|
+
@waiting = {}
|
30
|
+
@exclusive_thread = nil
|
31
|
+
@exclusive_depth = 0
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns false if +no_wait+ is set and the lock is not
|
35
|
+
# immediately available. Otherwise, returns true after the lock
|
36
|
+
# has been acquired.
|
37
|
+
#
|
38
|
+
# +purpose+ and +compatible+ work together; while this thread is
|
39
|
+
# waiting for the exclusive lock, it will yield its share (if any)
|
40
|
+
# to any other attempt whose +purpose+ appears in this attempt's
|
41
|
+
# +compatible+ list. This allows a "loose" upgrade, which, being
|
42
|
+
# less strict, prevents some classes of deadlocks.
|
43
|
+
#
|
44
|
+
# For many resources, loose upgrades are sufficient: if a thread
|
45
|
+
# is awaiting a lock, it is not running any other code. With
|
46
|
+
# +purpose+ matching, it is possible to yield only to other
|
47
|
+
# threads whose activity will not interfere.
|
48
|
+
def start_exclusive(purpose: nil, compatible: [], no_wait: false)
|
49
|
+
synchronize do
|
50
|
+
unless @exclusive_thread == Thread.current
|
51
|
+
if busy?(purpose)
|
52
|
+
return false if no_wait
|
53
|
+
|
54
|
+
loose_shares = @sharing.delete(Thread.current)
|
55
|
+
@waiting[Thread.current] = compatible if loose_shares
|
56
|
+
|
57
|
+
begin
|
58
|
+
@cv.wait_while { busy?(purpose) }
|
59
|
+
ensure
|
60
|
+
@waiting.delete Thread.current
|
61
|
+
@sharing[Thread.current] = loose_shares if loose_shares
|
62
|
+
end
|
63
|
+
end
|
64
|
+
@exclusive_thread = Thread.current
|
65
|
+
end
|
66
|
+
@exclusive_depth += 1
|
67
|
+
|
68
|
+
true
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Relinquish the exclusive lock. Must only be called by the thread
|
73
|
+
# that called start_exclusive (and currently holds the lock).
|
74
|
+
def stop_exclusive
|
75
|
+
synchronize do
|
76
|
+
raise "invalid unlock" if @exclusive_thread != Thread.current
|
77
|
+
|
78
|
+
@exclusive_depth -= 1
|
79
|
+
if @exclusive_depth == 0
|
80
|
+
@exclusive_thread = nil
|
81
|
+
@cv.broadcast
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def start_sharing
|
87
|
+
synchronize do
|
88
|
+
if @exclusive_thread && @exclusive_thread != Thread.current
|
89
|
+
@cv.wait_while { @exclusive_thread }
|
90
|
+
end
|
91
|
+
@sharing[Thread.current] += 1
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def stop_sharing
|
96
|
+
synchronize do
|
97
|
+
if @sharing[Thread.current] > 1
|
98
|
+
@sharing[Thread.current] -= 1
|
99
|
+
else
|
100
|
+
@sharing.delete Thread.current
|
101
|
+
@cv.broadcast
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Execute the supplied block while holding the Exclusive lock. If
|
107
|
+
# +no_wait+ is set and the lock is not immediately available,
|
108
|
+
# returns +nil+ without yielding. Otherwise, returns the result of
|
109
|
+
# the block.
|
110
|
+
#
|
111
|
+
# See +start_exclusive+ for other options.
|
112
|
+
def exclusive(purpose: nil, compatible: [], no_wait: false)
|
113
|
+
if start_exclusive(purpose: purpose, compatible: compatible, no_wait: no_wait)
|
114
|
+
begin
|
115
|
+
yield
|
116
|
+
ensure
|
117
|
+
stop_exclusive
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Execute the supplied block while holding the Share lock.
|
123
|
+
def sharing
|
124
|
+
start_sharing
|
125
|
+
begin
|
126
|
+
yield
|
127
|
+
ensure
|
128
|
+
stop_sharing
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
private
|
133
|
+
|
134
|
+
# Must be called within synchronize
|
135
|
+
def busy?(purpose)
|
136
|
+
(@exclusive_thread && @exclusive_thread != Thread.current) ||
|
137
|
+
@waiting.any? { |k, v| k != Thread.current && !v.include?(purpose) } ||
|
138
|
+
@sharing.size > (@sharing[Thread.current] > 0 ? 1 : 0)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -21,12 +21,24 @@ class Array
|
|
21
21
|
# %w( a b c ).to(-10) # => []
|
22
22
|
def to(position)
|
23
23
|
if position >= 0
|
24
|
-
|
24
|
+
take position + 1
|
25
25
|
else
|
26
26
|
self[0..position]
|
27
27
|
end
|
28
28
|
end
|
29
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
|
+
|
30
42
|
# Equal to <tt>self[1]</tt>.
|
31
43
|
#
|
32
44
|
# %w( a b c d e ).second # => "b"
|
@@ -32,7 +32,7 @@ class Array
|
|
32
32
|
# ['one', 'two', 'three'].to_sentence # => "one, two, and three"
|
33
33
|
#
|
34
34
|
# ['one', 'two'].to_sentence(passing: 'invalid option')
|
35
|
-
# # => ArgumentError: Unknown key :passing
|
35
|
+
# # => ArgumentError: Unknown key: :passing. Valid keys are: :words_connector, :two_words_connector, :last_word_connector, :locale
|
36
36
|
#
|
37
37
|
# ['one', 'two'].to_sentence(two_words_connector: '-')
|
38
38
|
# # => "one-two"
|
@@ -74,7 +74,7 @@ class Array
|
|
74
74
|
when 0
|
75
75
|
''
|
76
76
|
when 1
|
77
|
-
self[0]
|
77
|
+
"#{self[0]}"
|
78
78
|
when 2
|
79
79
|
"#{self[0]}#{options[:two_words_connector]}#{self[1]}"
|
80
80
|
else
|
@@ -85,14 +85,16 @@ class Array
|
|
85
85
|
# Extends <tt>Array#to_s</tt> to convert a collection of elements into a
|
86
86
|
# comma separated id list if <tt>:db</tt> argument is given as the format.
|
87
87
|
#
|
88
|
-
# Blog.all.to_formatted_s(:db)
|
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]"
|
89
91
|
def to_formatted_s(format = :default)
|
90
92
|
case format
|
91
93
|
when :db
|
92
94
|
if empty?
|
93
95
|
'null'
|
94
96
|
else
|
95
|
-
collect
|
97
|
+
collect(&:id).join(',')
|
96
98
|
end
|
97
99
|
else
|
98
100
|
to_default_s
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'active_support/array_inquirer'
|
2
|
+
|
3
|
+
class Array
|
4
|
+
# Wraps the array in an +ArrayInquirer+ object, which gives a friendlier way
|
5
|
+
# to check its string-like contents.
|
6
|
+
#
|
7
|
+
# pets = [:cat, :dog].inquiry
|
8
|
+
#
|
9
|
+
# pets.cat? # => true
|
10
|
+
# pets.ferret? # => false
|
11
|
+
#
|
12
|
+
# pets.any?(:cat, :ferret) # => true
|
13
|
+
# pets.any?(:ferret, :alligator) # => false
|
14
|
+
def inquiry
|
15
|
+
ActiveSupport::ArrayInquirer.new(self)
|
16
|
+
end
|
17
|
+
end
|
@@ -3,7 +3,7 @@ class Array
|
|
3
3
|
#
|
4
4
|
# Specifically:
|
5
5
|
#
|
6
|
-
# * If the argument is +nil+ an empty
|
6
|
+
# * If the argument is +nil+ an empty array is returned.
|
7
7
|
# * Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned.
|
8
8
|
# * Otherwise, returns an array with the argument as its single element.
|
9
9
|
#
|
@@ -15,12 +15,13 @@ class Array
|
|
15
15
|
#
|
16
16
|
# * If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt>
|
17
17
|
# moves on to try +to_a+ if the returned value is +nil+, but <tt>Array.wrap</tt> returns
|
18
|
-
#
|
18
|
+
# an array with the argument as its single element right away.
|
19
19
|
# * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt>
|
20
20
|
# raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value.
|
21
|
-
# * It does not call +to_a+ on the argument,
|
21
|
+
# * It does not call +to_a+ on the argument, if the argument does not respond to +to_ary+
|
22
|
+
# it returns an array with the argument as its single element.
|
22
23
|
#
|
23
|
-
# The
|
24
|
+
# The last point is easily explained with some enumerables:
|
24
25
|
#
|
25
26
|
# Array(foo: :bar) # => [[:foo, :bar]]
|
26
27
|
# Array.wrap(foo: :bar) # => [{:foo=>:bar}]
|
@@ -1,16 +1,14 @@
|
|
1
1
|
require 'bigdecimal'
|
2
2
|
require 'bigdecimal/util'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
format = args[0] || DEFAULT_STRING_FORMAT
|
11
|
-
_original_to_s(format)
|
4
|
+
module ActiveSupport
|
5
|
+
module BigDecimalWithDefaultFormat #:nodoc:
|
6
|
+
DEFAULT_STRING_FORMAT = 'F'
|
7
|
+
|
8
|
+
def to_s(format = nil)
|
9
|
+
super(format || DEFAULT_STRING_FORMAT)
|
12
10
|
end
|
13
11
|
end
|
14
|
-
alias_method :_original_to_s, :to_s
|
15
|
-
alias_method :to_s, :to_formatted_s
|
16
12
|
end
|
13
|
+
|
14
|
+
BigDecimal.prepend(ActiveSupport::BigDecimalWithDefaultFormat)
|
@@ -75,11 +75,15 @@ class Class
|
|
75
75
|
instance_predicate = options.fetch(:instance_predicate, true)
|
76
76
|
|
77
77
|
attrs.each do |name|
|
78
|
+
remove_possible_singleton_method(name)
|
78
79
|
define_singleton_method(name) { nil }
|
80
|
+
|
81
|
+
remove_possible_singleton_method("#{name}?")
|
79
82
|
define_singleton_method("#{name}?") { !!public_send(name) } if instance_predicate
|
80
83
|
|
81
84
|
ivar = "@#{name}"
|
82
85
|
|
86
|
+
remove_possible_singleton_method("#{name}=")
|
83
87
|
define_singleton_method("#{name}=") do |val|
|
84
88
|
singleton_class.class_eval do
|
85
89
|
remove_possible_method(name)
|
@@ -110,18 +114,15 @@ class Class
|
|
110
114
|
self.class.public_send name
|
111
115
|
end
|
112
116
|
end
|
117
|
+
|
118
|
+
remove_possible_method "#{name}?"
|
113
119
|
define_method("#{name}?") { !!public_send(name) } if instance_predicate
|
114
120
|
end
|
115
121
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
private
|
121
|
-
|
122
|
-
unless respond_to?(:singleton_class?)
|
123
|
-
def singleton_class?
|
124
|
-
ancestors.first != self
|
122
|
+
if instance_writer
|
123
|
+
remove_possible_method "#{name}="
|
124
|
+
attr_writer name
|
125
125
|
end
|
126
126
|
end
|
127
|
+
end
|
127
128
|
end
|
@@ -3,7 +3,8 @@ require 'active_support/core_ext/module/reachable'
|
|
3
3
|
|
4
4
|
class Class
|
5
5
|
begin
|
6
|
-
|
6
|
+
# Test if this Ruby supports each_object against singleton_class
|
7
|
+
ObjectSpace.each_object(Numeric.singleton_class) {}
|
7
8
|
|
8
9
|
def descendants # :nodoc:
|
9
10
|
descendants = []
|
@@ -12,7 +13,7 @@ class Class
|
|
12
13
|
end
|
13
14
|
descendants
|
14
15
|
end
|
15
|
-
rescue StandardError # JRuby
|
16
|
+
rescue StandardError # JRuby 9.0.4.0 and earlier
|
16
17
|
def descendants # :nodoc:
|
17
18
|
descendants = []
|
18
19
|
ObjectSpace.each_object(Class) do |k|
|
@@ -25,6 +26,8 @@ class Class
|
|
25
26
|
|
26
27
|
# Returns an array with the direct children of +self+.
|
27
28
|
#
|
29
|
+
# Integer.subclasses # => [Fixnum, Bignum]
|
30
|
+
#
|
28
31
|
# class Foo; end
|
29
32
|
# class Bar < Foo; end
|
30
33
|
# class Baz < Bar; end
|
@@ -26,7 +26,7 @@ class Date
|
|
26
26
|
Thread.current[:beginning_of_week] = find_beginning_of_week!(week_start)
|
27
27
|
end
|
28
28
|
|
29
|
-
# Returns week start day symbol (e.g. :monday), or raises an ArgumentError for invalid day symbol.
|
29
|
+
# Returns week start day symbol (e.g. :monday), or raises an +ArgumentError+ for invalid day symbol.
|
30
30
|
def find_beginning_of_week!(week_start)
|
31
31
|
raise ArgumentError, "Invalid beginning of week: #{week_start}" unless ::Date::DAYS_INTO_WEEK.key?(week_start)
|
32
32
|
week_start
|