activesupport 3.2.22.5 → 4.0.0
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 +364 -135
- data/MIT-LICENSE +1 -1
- data/README.rdoc +6 -4
- data/lib/active_support/backtrace_cleaner.rb +33 -25
- data/lib/active_support/basic_object.rb +7 -17
- data/lib/active_support/benchmarkable.rb +19 -15
- data/lib/active_support/buffered_logger.rb +9 -113
- data/lib/active_support/cache/file_store.rb +14 -14
- data/lib/active_support/cache/mem_cache_store.rb +24 -30
- data/lib/active_support/cache/memory_store.rb +2 -0
- data/lib/active_support/cache/strategy/local_cache.rb +48 -37
- data/lib/active_support/cache.rb +228 -183
- data/lib/active_support/callbacks.rb +201 -253
- data/lib/active_support/concern.rb +16 -23
- data/lib/active_support/concurrency/latch.rb +27 -0
- data/lib/active_support/configurable.rb +69 -12
- data/lib/active_support/core_ext/array/access.rb +17 -9
- data/lib/active_support/core_ext/array/conversions.rb +115 -55
- data/lib/active_support/core_ext/array/extract_options.rb +2 -2
- data/lib/active_support/core_ext/array/grouping.rb +21 -22
- data/lib/active_support/core_ext/array/uniq_by.rb +12 -9
- data/lib/active_support/core_ext/array/wrap.rb +13 -16
- data/lib/active_support/core_ext/array.rb +0 -1
- data/lib/active_support/core_ext/benchmark.rb +7 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -24
- data/lib/active_support/core_ext/class/attribute.rb +40 -32
- data/lib/active_support/core_ext/class/attribute_accessors.rb +14 -12
- data/lib/active_support/core_ext/class/delegating_attributes.rb +15 -19
- data/lib/active_support/core_ext/class/subclasses.rb +11 -5
- data/lib/active_support/core_ext/date/calculations.rb +44 -187
- data/lib/active_support/core_ext/date/conversions.rb +16 -38
- data/lib/active_support/core_ext/date/zones.rb +25 -2
- data/lib/active_support/core_ext/date.rb +5 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +232 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +0 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +77 -62
- data/lib/active_support/core_ext/date_time/conversions.rb +21 -33
- data/lib/active_support/core_ext/date_time/zones.rb +11 -8
- data/lib/active_support/core_ext/date_time.rb +4 -0
- data/lib/active_support/core_ext/enumerable.rb +26 -73
- data/lib/active_support/core_ext/file/atomic.rb +27 -11
- data/lib/active_support/core_ext/file.rb +0 -1
- data/lib/active_support/core_ext/hash/conversions.rb +145 -79
- data/lib/active_support/core_ext/hash/deep_merge.rb +14 -8
- data/lib/active_support/core_ext/hash/diff.rb +5 -4
- data/lib/active_support/core_ext/hash/except.rb +1 -9
- data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -5
- data/lib/active_support/core_ext/hash/keys.rb +108 -24
- data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -3
- data/lib/active_support/core_ext/hash/slice.rb +12 -12
- data/lib/active_support/core_ext/hash.rb +0 -1
- data/lib/active_support/core_ext/integer/inflections.rb +13 -1
- data/lib/active_support/core_ext/integer/time.rb +17 -12
- data/lib/active_support/core_ext/kernel/debugger.rb +2 -2
- data/lib/active_support/core_ext/kernel/reporting.rb +36 -22
- data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -7
- data/lib/active_support/core_ext/load_error.rb +7 -5
- data/lib/active_support/core_ext/logger.rb +7 -23
- data/lib/active_support/core_ext/marshal.rb +21 -0
- data/lib/active_support/core_ext/module/aliasing.rb +8 -9
- data/lib/active_support/core_ext/module/anonymous.rb +2 -7
- data/lib/active_support/core_ext/module/attr_internal.rb +0 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +12 -10
- data/lib/active_support/core_ext/module/delegation.rb +92 -49
- data/lib/active_support/core_ext/module/deprecation.rb +19 -3
- data/lib/active_support/core_ext/module/introspection.rb +17 -27
- data/lib/active_support/core_ext/module/qualified_const.rb +8 -20
- data/lib/active_support/core_ext/module/remove_method.rb +1 -5
- data/lib/active_support/core_ext/module.rb +1 -3
- data/lib/active_support/core_ext/numeric/conversions.rb +135 -0
- data/lib/active_support/core_ext/numeric/time.rb +6 -6
- data/lib/active_support/core_ext/numeric.rb +1 -0
- data/lib/active_support/core_ext/object/acts_like.rb +4 -4
- data/lib/active_support/core_ext/object/blank.rb +7 -23
- data/lib/active_support/core_ext/object/deep_dup.rb +46 -0
- data/lib/active_support/core_ext/object/duplicable.rb +1 -30
- data/lib/active_support/core_ext/object/inclusion.rb +8 -7
- data/lib/active_support/core_ext/object/instance_variables.rb +7 -12
- data/lib/active_support/core_ext/object/to_json.rb +8 -0
- data/lib/active_support/core_ext/object/to_param.rb +5 -2
- data/lib/active_support/core_ext/object/try.rb +46 -25
- data/lib/active_support/core_ext/object/with_options.rb +7 -8
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/proc.rb +3 -0
- data/lib/active_support/core_ext/range/conversions.rb +0 -2
- data/lib/active_support/core_ext/range/include_range.rb +3 -1
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/range.rb +0 -2
- data/lib/active_support/core_ext/string/access.rb +95 -90
- data/lib/active_support/core_ext/string/conversions.rb +27 -38
- data/lib/active_support/core_ext/string/encoding.rb +6 -9
- data/lib/active_support/core_ext/string/filters.rb +24 -18
- data/lib/active_support/core_ext/string/indent.rb +43 -0
- data/lib/active_support/core_ext/string/inflections.rb +70 -60
- data/lib/active_support/core_ext/string/inquiry.rb +2 -2
- data/lib/active_support/core_ext/string/multibyte.rb +41 -64
- data/lib/active_support/core_ext/string/output_safety.rb +59 -51
- data/lib/active_support/core_ext/string/zones.rb +13 -0
- data/lib/active_support/core_ext/string.rb +2 -3
- data/lib/active_support/core_ext/struct.rb +6 -0
- data/lib/active_support/core_ext/thread.rb +74 -0
- data/lib/active_support/core_ext/time/calculations.rb +108 -184
- data/lib/active_support/core_ext/time/conversions.rb +27 -51
- data/lib/active_support/core_ext/time/marshal.rb +0 -27
- data/lib/active_support/core_ext/time/zones.rb +27 -17
- data/lib/active_support/core_ext/time.rb +5 -0
- data/lib/active_support/core_ext/uri.rb +13 -17
- data/lib/active_support/core_ext.rb +3 -2
- data/lib/active_support/dependencies/autoload.rb +47 -20
- data/lib/active_support/dependencies.rb +160 -141
- data/lib/active_support/deprecation/behaviors.rb +44 -30
- data/lib/active_support/deprecation/instance_delegator.rb +24 -0
- data/lib/active_support/deprecation/method_wrappers.rb +33 -18
- data/lib/active_support/deprecation/proxy_wrappers.rb +58 -13
- data/lib/active_support/deprecation/reporting.rb +40 -11
- data/lib/active_support/deprecation.rb +39 -14
- data/lib/active_support/descendants_tracker.rb +34 -19
- data/lib/active_support/duration.rb +6 -8
- data/lib/active_support/file_update_checker.rb +63 -47
- data/lib/active_support/gzip.rb +11 -5
- data/lib/active_support/hash_with_indifferent_access.rb +127 -42
- data/lib/active_support/i18n.rb +4 -0
- data/lib/active_support/i18n_railtie.rb +5 -22
- data/lib/active_support/inflections.rb +14 -12
- data/lib/active_support/inflector/inflections.rb +108 -71
- data/lib/active_support/inflector/methods.rb +181 -160
- data/lib/active_support/inflector/transliterate.rb +16 -17
- data/lib/active_support/json/decoding.rb +18 -17
- data/lib/active_support/json/encoding.rb +93 -39
- data/lib/active_support/json/variable.rb +10 -1
- data/lib/active_support/key_generator.rb +75 -0
- data/lib/active_support/lazy_load_hooks.rb +21 -19
- data/lib/active_support/locale/en.yml +100 -3
- data/lib/active_support/log_subscriber/test_helper.rb +18 -15
- data/lib/active_support/log_subscriber.rb +35 -52
- data/lib/active_support/logger.rb +57 -0
- data/lib/active_support/logger_silence.rb +24 -0
- data/lib/active_support/message_encryptor.rb +38 -35
- data/lib/active_support/message_verifier.rb +9 -15
- data/lib/active_support/multibyte/chars.rb +80 -333
- data/lib/active_support/multibyte/unicode.rb +74 -64
- data/lib/active_support/multibyte.rb +5 -28
- data/lib/active_support/notifications/fanout.rb +112 -18
- data/lib/active_support/notifications/instrumenter.rb +33 -14
- data/lib/active_support/notifications.rb +79 -26
- data/lib/active_support/number_helper.rb +637 -0
- data/lib/active_support/ordered_hash.rb +8 -190
- data/lib/active_support/ordered_options.rb +21 -23
- data/lib/active_support/per_thread_registry.rb +52 -0
- data/lib/active_support/proxy_object.rb +13 -0
- data/lib/active_support/rails.rb +27 -0
- data/lib/active_support/railtie.rb +12 -32
- data/lib/active_support/rescuable.rb +9 -4
- data/lib/active_support/string_inquirer.rb +13 -8
- data/lib/active_support/subscriber.rb +93 -0
- data/lib/active_support/tagged_logging.rb +51 -73
- data/lib/active_support/test_case.rb +46 -17
- data/lib/active_support/testing/assertions.rb +56 -26
- data/lib/active_support/testing/autorun.rb +5 -0
- data/lib/active_support/testing/constant_lookup.rb +54 -0
- data/lib/active_support/testing/declarative.rb +1 -1
- data/lib/active_support/testing/deprecation.rb +0 -19
- data/lib/active_support/testing/isolation.rb +29 -58
- data/lib/active_support/testing/pending.rb +5 -43
- data/lib/active_support/testing/setup_and_teardown.rb +6 -92
- data/lib/active_support/testing/tagged_logging.rb +25 -0
- data/lib/active_support/time.rb +6 -21
- data/lib/active_support/time_with_zone.rb +80 -43
- data/lib/active_support/values/time_zone.rb +81 -60
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +7 -6
- data/lib/active_support/xml_mini/jdom.rb +9 -11
- data/lib/active_support/xml_mini/libxml.rb +1 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +2 -3
- data/lib/active_support/xml_mini/nokogiri.rb +1 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +2 -3
- data/lib/active_support/xml_mini/rexml.rb +6 -8
- data/lib/active_support/xml_mini.rb +35 -17
- data/lib/active_support.rb +8 -21
- metadata +104 -72
- data/lib/active_support/base64.rb +0 -54
- data/lib/active_support/core_ext/array/random_access.rb +0 -30
- data/lib/active_support/core_ext/date/freeze.rb +0 -33
- data/lib/active_support/core_ext/exception.rb +0 -3
- data/lib/active_support/core_ext/file/path.rb +0 -5
- data/lib/active_support/core_ext/float/rounding.rb +0 -19
- data/lib/active_support/core_ext/float.rb +0 -1
- data/lib/active_support/core_ext/hash/deep_dup.rb +0 -18
- data/lib/active_support/core_ext/io.rb +0 -15
- data/lib/active_support/core_ext/module/method_names.rb +0 -14
- data/lib/active_support/core_ext/module/synchronization.rb +0 -45
- data/lib/active_support/core_ext/process/daemon.rb +0 -23
- data/lib/active_support/core_ext/process.rb +0 -1
- data/lib/active_support/core_ext/range/blockless_step.rb +0 -29
- data/lib/active_support/core_ext/range/cover.rb +0 -3
- data/lib/active_support/core_ext/rexml.rb +0 -46
- data/lib/active_support/core_ext/string/interpolation.rb +0 -2
- data/lib/active_support/core_ext/string/xchar.rb +0 -18
- data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +0 -10
- data/lib/active_support/memoizable.rb +0 -116
- data/lib/active_support/multibyte/exceptions.rb +0 -8
- data/lib/active_support/multibyte/utils.rb +0 -60
- data/lib/active_support/ruby/shim.rb +0 -22
- data/lib/active_support/security_utils.rb +0 -27
- data/lib/active_support/testing/mochaing.rb +0 -7
- data/lib/active_support/testing/performance/jruby.rb +0 -115
- data/lib/active_support/testing/performance/rubinius.rb +0 -113
- data/lib/active_support/testing/performance/ruby/mri.rb +0 -57
- data/lib/active_support/testing/performance/ruby/yarv.rb +0 -57
- data/lib/active_support/testing/performance/ruby.rb +0 -152
- data/lib/active_support/testing/performance.rb +0 -317
- data/lib/active_support/time/autoload.rb +0 -5
- data/lib/active_support/whiny_nil.rb +0 -24
|
@@ -5,17 +5,18 @@ module ActiveSupport
|
|
|
5
5
|
|
|
6
6
|
extend self
|
|
7
7
|
|
|
8
|
-
# A list of all available normalization forms.
|
|
8
|
+
# A list of all available normalization forms.
|
|
9
|
+
# See http://www.unicode.org/reports/tr15/tr15-29.html for more
|
|
9
10
|
# information about normalization.
|
|
10
11
|
NORMALIZATION_FORMS = [:c, :kc, :d, :kd]
|
|
11
12
|
|
|
12
13
|
# The Unicode version that is supported by the implementation
|
|
13
|
-
UNICODE_VERSION = '
|
|
14
|
+
UNICODE_VERSION = '6.2.0'
|
|
14
15
|
|
|
15
|
-
# The default normalization used for operations that require
|
|
16
|
-
#
|
|
16
|
+
# The default normalization used for operations that require
|
|
17
|
+
# normalization. It can be set to any of the normalizations
|
|
18
|
+
# in NORMALIZATION_FORMS.
|
|
17
19
|
#
|
|
18
|
-
# Example:
|
|
19
20
|
# ActiveSupport::Multibyte::Unicode.default_normalization_form = :c
|
|
20
21
|
attr_accessor :default_normalization_form
|
|
21
22
|
@default_normalization_form = :kc
|
|
@@ -50,32 +51,22 @@ module ActiveSupport
|
|
|
50
51
|
0x3000, # White_Space # Zs IDEOGRAPHIC SPACE
|
|
51
52
|
].flatten.freeze
|
|
52
53
|
|
|
53
|
-
# BOM (byte order mark) can also be seen as whitespace, it's a
|
|
54
|
-
#
|
|
54
|
+
# BOM (byte order mark) can also be seen as whitespace, it's a
|
|
55
|
+
# non-rendering character used to distinguish between little and big
|
|
56
|
+
# endian. This is not an issue in utf-8, so it must be ignored.
|
|
55
57
|
LEADERS_AND_TRAILERS = WHITESPACE + [65279] # ZERO-WIDTH NO-BREAK SPACE aka BOM
|
|
56
58
|
|
|
57
|
-
# Returns a regular expression pattern that matches the passed Unicode
|
|
59
|
+
# Returns a regular expression pattern that matches the passed Unicode
|
|
60
|
+
# codepoints.
|
|
58
61
|
def self.codepoints_to_pattern(array_of_codepoints) #:nodoc:
|
|
59
62
|
array_of_codepoints.collect{ |e| [e].pack 'U*' }.join('|')
|
|
60
63
|
end
|
|
61
64
|
TRAILERS_PAT = /(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+\Z/u
|
|
62
65
|
LEADERS_PAT = /\A(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+/u
|
|
63
66
|
|
|
64
|
-
#
|
|
65
|
-
#
|
|
66
|
-
#
|
|
67
|
-
# Example:
|
|
68
|
-
# Unicode.u_unpack('Café') # => [67, 97, 102, 233]
|
|
69
|
-
def u_unpack(string)
|
|
70
|
-
begin
|
|
71
|
-
string.unpack 'U*'
|
|
72
|
-
rescue ArgumentError
|
|
73
|
-
raise EncodingError, 'malformed UTF-8 character'
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
# Detect whether the codepoint is in a certain character class. Returns +true+ when it's in the specified
|
|
78
|
-
# character class and +false+ otherwise. Valid character classes are: <tt>:cr</tt>, <tt>:lf</tt>, <tt>:l</tt>,
|
|
67
|
+
# Detect whether the codepoint is in a certain character class. Returns
|
|
68
|
+
# +true+ when it's in the specified character class and +false+ otherwise.
|
|
69
|
+
# Valid character classes are: <tt>:cr</tt>, <tt>:lf</tt>, <tt>:l</tt>,
|
|
79
70
|
# <tt>:v</tt>, <tt>:lv</tt>, <tt>:lvt</tt> and <tt>:t</tt>.
|
|
80
71
|
#
|
|
81
72
|
# Primarily used by the grapheme cluster support.
|
|
@@ -83,13 +74,13 @@ module ActiveSupport
|
|
|
83
74
|
classes.detect { |c| database.boundary[c] === codepoint } ? true : false
|
|
84
75
|
end
|
|
85
76
|
|
|
86
|
-
# Unpack the string at grapheme boundaries. Returns a list of character
|
|
77
|
+
# Unpack the string at grapheme boundaries. Returns a list of character
|
|
78
|
+
# lists.
|
|
87
79
|
#
|
|
88
|
-
#
|
|
89
|
-
# Unicode.
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
codepoints = u_unpack(string)
|
|
80
|
+
# Unicode.unpack_graphemes('क्षि') # => [[2325, 2381], [2359], [2367]]
|
|
81
|
+
# Unicode.unpack_graphemes('Café') # => [[67], [97], [102], [233]]
|
|
82
|
+
def unpack_graphemes(string)
|
|
83
|
+
codepoints = string.codepoints.to_a
|
|
93
84
|
unpacked = []
|
|
94
85
|
pos = 0
|
|
95
86
|
marker = 0
|
|
@@ -118,12 +109,11 @@ module ActiveSupport
|
|
|
118
109
|
unpacked
|
|
119
110
|
end
|
|
120
111
|
|
|
121
|
-
# Reverse operation of
|
|
112
|
+
# Reverse operation of unpack_graphemes.
|
|
122
113
|
#
|
|
123
|
-
#
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
(unpacked.flatten).pack('U*')
|
|
114
|
+
# Unicode.pack_graphemes(Unicode.unpack_graphemes('क्षि')) # => 'क्षि'
|
|
115
|
+
def pack_graphemes(unpacked)
|
|
116
|
+
unpacked.flatten.pack('U*')
|
|
127
117
|
end
|
|
128
118
|
|
|
129
119
|
# Re-order codepoints so the string becomes canonical.
|
|
@@ -143,7 +133,7 @@ module ActiveSupport
|
|
|
143
133
|
end
|
|
144
134
|
|
|
145
135
|
# Decompose composed characters to the decomposed form.
|
|
146
|
-
def
|
|
136
|
+
def decompose(type, codepoints)
|
|
147
137
|
codepoints.inject([]) do |decomposed, cp|
|
|
148
138
|
# if it's a hangul syllable starter character
|
|
149
139
|
if HANGUL_SBASE <= cp and cp < HANGUL_SLAST
|
|
@@ -156,7 +146,7 @@ module ActiveSupport
|
|
|
156
146
|
decomposed.concat ncp
|
|
157
147
|
# if the codepoint is decomposable in with the current decomposition type
|
|
158
148
|
elsif (ncp = database.codepoints[cp].decomp_mapping) and (!database.codepoints[cp].decomp_type || type == :compatability)
|
|
159
|
-
decomposed.concat
|
|
149
|
+
decomposed.concat decompose(type, ncp.dup)
|
|
160
150
|
else
|
|
161
151
|
decomposed << cp
|
|
162
152
|
end
|
|
@@ -164,7 +154,7 @@ module ActiveSupport
|
|
|
164
154
|
end
|
|
165
155
|
|
|
166
156
|
# Compose decomposed characters to the composed form.
|
|
167
|
-
def
|
|
157
|
+
def compose(codepoints)
|
|
168
158
|
pos = 0
|
|
169
159
|
eoa = codepoints.length - 1
|
|
170
160
|
starter_pos = 0
|
|
@@ -222,9 +212,11 @@ module ActiveSupport
|
|
|
222
212
|
codepoints
|
|
223
213
|
end
|
|
224
214
|
|
|
225
|
-
# Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent
|
|
215
|
+
# Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent
|
|
216
|
+
# resulting in a valid UTF-8 string.
|
|
226
217
|
#
|
|
227
|
-
# Passing +true+ will forcibly tidy all bytes, assuming that the string's
|
|
218
|
+
# Passing +true+ will forcibly tidy all bytes, assuming that the string's
|
|
219
|
+
# encoding is entirely CP1252 or ISO-8859-1.
|
|
228
220
|
def tidy_bytes(string, force = false)
|
|
229
221
|
if force
|
|
230
222
|
return string.unpack("C*").map do |b|
|
|
@@ -273,48 +265,54 @@ module ActiveSupport
|
|
|
273
265
|
bytes.empty? ? "" : bytes.flatten.compact.pack("C*").unpack("U*").pack("U*")
|
|
274
266
|
end
|
|
275
267
|
|
|
276
|
-
# Returns the KC normalization of the string by default. NFKC is
|
|
277
|
-
# passing strings to databases
|
|
268
|
+
# Returns the KC normalization of the string by default. NFKC is
|
|
269
|
+
# considered the best normalization form for passing strings to databases
|
|
270
|
+
# and validations.
|
|
278
271
|
#
|
|
279
272
|
# * <tt>string</tt> - The string to perform normalization on.
|
|
280
|
-
# * <tt>form</tt> - The form you want to normalize in. Should be one of
|
|
281
|
-
# <tt>:c</tt>, <tt>:kc</tt>, <tt>:d</tt>, or <tt>:kd</tt>.
|
|
282
|
-
# ActiveSupport::Multibyte.default_normalization_form
|
|
273
|
+
# * <tt>form</tt> - The form you want to normalize in. Should be one of
|
|
274
|
+
# the following: <tt>:c</tt>, <tt>:kc</tt>, <tt>:d</tt>, or <tt>:kd</tt>.
|
|
275
|
+
# Default is ActiveSupport::Multibyte.default_normalization_form.
|
|
283
276
|
def normalize(string, form=nil)
|
|
284
277
|
form ||= @default_normalization_form
|
|
285
278
|
# See http://www.unicode.org/reports/tr15, Table 1
|
|
286
|
-
codepoints =
|
|
279
|
+
codepoints = string.codepoints.to_a
|
|
287
280
|
case form
|
|
288
281
|
when :d
|
|
289
|
-
reorder_characters(
|
|
282
|
+
reorder_characters(decompose(:canonical, codepoints))
|
|
290
283
|
when :c
|
|
291
|
-
|
|
284
|
+
compose(reorder_characters(decompose(:canonical, codepoints)))
|
|
292
285
|
when :kd
|
|
293
|
-
reorder_characters(
|
|
286
|
+
reorder_characters(decompose(:compatability, codepoints))
|
|
294
287
|
when :kc
|
|
295
|
-
|
|
288
|
+
compose(reorder_characters(decompose(:compatability, codepoints)))
|
|
296
289
|
else
|
|
297
290
|
raise ArgumentError, "#{form} is not a valid normalization variant", caller
|
|
298
291
|
end.pack('U*')
|
|
299
292
|
end
|
|
300
293
|
|
|
301
|
-
def
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
codepoint
|
|
308
|
-
end
|
|
309
|
-
end.pack('U*')
|
|
294
|
+
def downcase(string)
|
|
295
|
+
apply_mapping string, :lowercase_mapping
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
def upcase(string)
|
|
299
|
+
apply_mapping string, :uppercase_mapping
|
|
310
300
|
end
|
|
311
301
|
|
|
312
|
-
|
|
302
|
+
def swapcase(string)
|
|
303
|
+
apply_mapping string, :swapcase_mapping
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# Holds data about a codepoint in the Unicode database.
|
|
313
307
|
class Codepoint
|
|
314
308
|
attr_accessor :code, :combining_class, :decomp_type, :decomp_mapping, :uppercase_mapping, :lowercase_mapping
|
|
309
|
+
|
|
310
|
+
def swapcase_mapping
|
|
311
|
+
uppercase_mapping > 0 ? uppercase_mapping : lowercase_mapping
|
|
312
|
+
end
|
|
315
313
|
end
|
|
316
314
|
|
|
317
|
-
# Holds static data from the Unicode database
|
|
315
|
+
# Holds static data from the Unicode database.
|
|
318
316
|
class UnicodeDatabase
|
|
319
317
|
ATTRIBUTES = :codepoints, :composition_exclusion, :composition_map, :boundary, :cp1252
|
|
320
318
|
|
|
@@ -338,11 +336,12 @@ module ActiveSupport
|
|
|
338
336
|
EOS
|
|
339
337
|
end
|
|
340
338
|
|
|
341
|
-
# Loads the Unicode database and returns all the internal objects of
|
|
339
|
+
# Loads the Unicode database and returns all the internal objects of
|
|
340
|
+
# UnicodeDatabase.
|
|
342
341
|
def load
|
|
343
342
|
begin
|
|
344
343
|
@codepoints, @composition_exclusion, @composition_map, @boundary, @cp1252 = File.open(self.class.filename, 'rb') { |f| Marshal.load f.read }
|
|
345
|
-
rescue
|
|
344
|
+
rescue => e
|
|
346
345
|
raise IOError.new("Couldn't load the Unicode tables for UTF8Handler (#{e.message}), ActiveSupport::Multibyte is unusable")
|
|
347
346
|
end
|
|
348
347
|
|
|
@@ -361,12 +360,12 @@ module ActiveSupport
|
|
|
361
360
|
end
|
|
362
361
|
end
|
|
363
362
|
|
|
364
|
-
# Returns the directory in which the data files are stored
|
|
363
|
+
# Returns the directory in which the data files are stored.
|
|
365
364
|
def self.dirname
|
|
366
365
|
File.dirname(__FILE__) + '/../values/'
|
|
367
366
|
end
|
|
368
367
|
|
|
369
|
-
# Returns the filename for the data file for this version
|
|
368
|
+
# Returns the filename for the data file for this version.
|
|
370
369
|
def self.filename
|
|
371
370
|
File.expand_path File.join(dirname, "unicode_tables.dat")
|
|
372
371
|
end
|
|
@@ -374,6 +373,17 @@ module ActiveSupport
|
|
|
374
373
|
|
|
375
374
|
private
|
|
376
375
|
|
|
376
|
+
def apply_mapping(string, mapping) #:nodoc:
|
|
377
|
+
string.each_codepoint.map do |codepoint|
|
|
378
|
+
cp = database.codepoints[codepoint]
|
|
379
|
+
if cp and (ncp = cp.send(mapping)) and ncp > 0
|
|
380
|
+
ncp
|
|
381
|
+
else
|
|
382
|
+
codepoint
|
|
383
|
+
end
|
|
384
|
+
end.pack('U*')
|
|
385
|
+
end
|
|
386
|
+
|
|
377
387
|
def tidy_byte(byte)
|
|
378
388
|
if byte < 160
|
|
379
389
|
[database.cp1252[byte] || byte].pack("U").unpack("C*")
|
|
@@ -1,44 +1,21 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
require 'active_support/core_ext/module/attribute_accessors'
|
|
3
|
-
|
|
4
1
|
module ActiveSupport #:nodoc:
|
|
5
2
|
module Multibyte
|
|
6
|
-
autoload :EncodingError, 'active_support/multibyte/exceptions'
|
|
7
3
|
autoload :Chars, 'active_support/multibyte/chars'
|
|
8
4
|
autoload :Unicode, 'active_support/multibyte/unicode'
|
|
9
5
|
|
|
10
|
-
# The proxy class returned when calling mb_chars. You can use this accessor
|
|
11
|
-
# class so you can support other encodings. See
|
|
12
|
-
# an example how to
|
|
6
|
+
# The proxy class returned when calling mb_chars. You can use this accessor
|
|
7
|
+
# to configure your own proxy class so you can support other encodings. See
|
|
8
|
+
# the ActiveSupport::Multibyte::Chars implementation for an example how to
|
|
9
|
+
# do this.
|
|
13
10
|
#
|
|
14
|
-
# Example:
|
|
15
11
|
# ActiveSupport::Multibyte.proxy_class = CharsForUTF32
|
|
16
12
|
def self.proxy_class=(klass)
|
|
17
13
|
@proxy_class = klass
|
|
18
14
|
end
|
|
19
15
|
|
|
20
|
-
# Returns the current proxy class
|
|
16
|
+
# Returns the current proxy class.
|
|
21
17
|
def self.proxy_class
|
|
22
18
|
@proxy_class ||= ActiveSupport::Multibyte::Chars
|
|
23
19
|
end
|
|
24
|
-
|
|
25
|
-
# Regular expressions that describe valid byte sequences for a character
|
|
26
|
-
VALID_CHARACTER = {
|
|
27
|
-
# Borrowed from the Kconv library by Shinji KONO - (also as seen on the W3C site)
|
|
28
|
-
'UTF-8' => /\A(?:
|
|
29
|
-
[\x00-\x7f] |
|
|
30
|
-
[\xc2-\xdf] [\x80-\xbf] |
|
|
31
|
-
\xe0 [\xa0-\xbf] [\x80-\xbf] |
|
|
32
|
-
[\xe1-\xef] [\x80-\xbf] [\x80-\xbf] |
|
|
33
|
-
\xf0 [\x90-\xbf] [\x80-\xbf] [\x80-\xbf] |
|
|
34
|
-
[\xf1-\xf3] [\x80-\xbf] [\x80-\xbf] [\x80-\xbf] |
|
|
35
|
-
\xf4 [\x80-\x8f] [\x80-\xbf] [\x80-\xbf])\z /xn,
|
|
36
|
-
# Quick check for valid Shift-JIS characters, disregards the odd-even pairing
|
|
37
|
-
'Shift_JIS' => /\A(?:
|
|
38
|
-
[\x00-\x7e\xa1-\xdf] |
|
|
39
|
-
[\x81-\x9f\xe0-\xef] [\x40-\x7e\x80-\x9e\x9f-\xfc])\z /xn
|
|
40
|
-
}
|
|
41
20
|
end
|
|
42
21
|
end
|
|
43
|
-
|
|
44
|
-
require 'active_support/multibyte/utils'
|
|
@@ -1,24 +1,43 @@
|
|
|
1
|
+
require 'mutex_m'
|
|
2
|
+
require 'thread_safe'
|
|
3
|
+
|
|
1
4
|
module ActiveSupport
|
|
2
5
|
module Notifications
|
|
3
6
|
# This is a default queue implementation that ships with Notifications.
|
|
4
7
|
# It just pushes events to all registered log subscribers.
|
|
8
|
+
#
|
|
9
|
+
# This class is thread safe. All methods are reentrant.
|
|
5
10
|
class Fanout
|
|
11
|
+
include Mutex_m
|
|
12
|
+
|
|
6
13
|
def initialize
|
|
7
14
|
@subscribers = []
|
|
8
|
-
@listeners_for =
|
|
15
|
+
@listeners_for = ThreadSafe::Cache.new
|
|
16
|
+
super
|
|
9
17
|
end
|
|
10
18
|
|
|
11
19
|
def subscribe(pattern = nil, block = Proc.new)
|
|
12
|
-
subscriber =
|
|
13
|
-
|
|
20
|
+
subscriber = Subscribers.new pattern, block
|
|
21
|
+
synchronize do
|
|
22
|
+
@subscribers << subscriber
|
|
23
|
+
@listeners_for.clear
|
|
14
24
|
end
|
|
15
|
-
@listeners_for.clear
|
|
16
25
|
subscriber
|
|
17
26
|
end
|
|
18
27
|
|
|
19
28
|
def unsubscribe(subscriber)
|
|
20
|
-
|
|
21
|
-
|
|
29
|
+
synchronize do
|
|
30
|
+
@subscribers.reject! { |s| s.matches?(subscriber) }
|
|
31
|
+
@listeners_for.clear
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def start(name, id, payload)
|
|
36
|
+
listeners_for(name).each { |s| s.start(name, id, payload) }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def finish(name, id, payload)
|
|
40
|
+
listeners_for(name).each { |s| s.finish(name, id, payload) }
|
|
22
41
|
end
|
|
23
42
|
|
|
24
43
|
def publish(name, *args)
|
|
@@ -26,7 +45,11 @@ module ActiveSupport
|
|
|
26
45
|
end
|
|
27
46
|
|
|
28
47
|
def listeners_for(name)
|
|
29
|
-
|
|
48
|
+
# this is correctly done double-checked locking (ThreadSafe::Cache's lookups have volatile semantics)
|
|
49
|
+
@listeners_for[name] || synchronize do
|
|
50
|
+
# use synchronisation when accessing @subscribers
|
|
51
|
+
@listeners_for[name] ||= @subscribers.select { |s| s.subscribed_to?(name) }
|
|
52
|
+
end
|
|
30
53
|
end
|
|
31
54
|
|
|
32
55
|
def listening?(name)
|
|
@@ -37,23 +60,94 @@ module ActiveSupport
|
|
|
37
60
|
def wait
|
|
38
61
|
end
|
|
39
62
|
|
|
40
|
-
|
|
41
|
-
def
|
|
42
|
-
|
|
43
|
-
|
|
63
|
+
module Subscribers # :nodoc:
|
|
64
|
+
def self.new(pattern, listener)
|
|
65
|
+
if listener.respond_to?(:start) and listener.respond_to?(:finish)
|
|
66
|
+
subscriber = Evented.new pattern, listener
|
|
67
|
+
else
|
|
68
|
+
subscriber = Timed.new pattern, listener
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
unless pattern
|
|
72
|
+
AllMessages.new(subscriber)
|
|
73
|
+
else
|
|
74
|
+
subscriber
|
|
75
|
+
end
|
|
44
76
|
end
|
|
45
77
|
|
|
46
|
-
|
|
47
|
-
|
|
78
|
+
class Evented #:nodoc:
|
|
79
|
+
def initialize(pattern, delegate)
|
|
80
|
+
@pattern = pattern
|
|
81
|
+
@delegate = delegate
|
|
82
|
+
@can_publish = delegate.respond_to?(:publish)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def publish(name, *args)
|
|
86
|
+
if @can_publish
|
|
87
|
+
@delegate.publish name, *args
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def start(name, id, payload)
|
|
92
|
+
@delegate.start name, id, payload
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def finish(name, id, payload)
|
|
96
|
+
@delegate.finish name, id, payload
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def subscribed_to?(name)
|
|
100
|
+
@pattern === name.to_s
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def matches?(subscriber_or_name)
|
|
104
|
+
self === subscriber_or_name ||
|
|
105
|
+
@pattern && @pattern === subscriber_or_name
|
|
106
|
+
end
|
|
48
107
|
end
|
|
49
108
|
|
|
50
|
-
|
|
51
|
-
|
|
109
|
+
class Timed < Evented
|
|
110
|
+
def initialize(pattern, delegate)
|
|
111
|
+
@timestack = []
|
|
112
|
+
super
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def publish(name, *args)
|
|
116
|
+
@delegate.call name, *args
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def start(name, id, payload)
|
|
120
|
+
@timestack.push Time.now
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def finish(name, id, payload)
|
|
124
|
+
started = @timestack.pop
|
|
125
|
+
@delegate.call(name, started, Time.now, id, payload)
|
|
126
|
+
end
|
|
52
127
|
end
|
|
53
128
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
@
|
|
129
|
+
class AllMessages # :nodoc:
|
|
130
|
+
def initialize(delegate)
|
|
131
|
+
@delegate = delegate
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def start(name, id, payload)
|
|
135
|
+
@delegate.start name, id, payload
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def finish(name, id, payload)
|
|
139
|
+
@delegate.finish name, id, payload
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def publish(name, *args)
|
|
143
|
+
@delegate.publish name, *args
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def subscribed_to?(name)
|
|
147
|
+
true
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
alias :matches? :===
|
|
57
151
|
end
|
|
58
152
|
end
|
|
59
153
|
end
|
|
@@ -1,39 +1,51 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'securerandom'
|
|
2
2
|
|
|
3
3
|
module ActiveSupport
|
|
4
4
|
module Notifications
|
|
5
|
+
# Instrumenters are stored in a thread local.
|
|
5
6
|
class Instrumenter
|
|
6
7
|
attr_reader :id
|
|
7
8
|
|
|
8
9
|
def initialize(notifier)
|
|
9
|
-
@id
|
|
10
|
+
@id = unique_id
|
|
10
11
|
@notifier = notifier
|
|
11
12
|
end
|
|
12
13
|
|
|
13
14
|
# Instrument the given block by measuring the time taken to execute it
|
|
14
15
|
# and publish it. Notice that events get sent even if an error occurs
|
|
15
|
-
# in the passed-in block
|
|
16
|
+
# in the passed-in block.
|
|
16
17
|
def instrument(name, payload={})
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
start name, payload
|
|
19
19
|
begin
|
|
20
|
-
yield
|
|
20
|
+
yield payload
|
|
21
21
|
rescue Exception => e
|
|
22
22
|
payload[:exception] = [e.class.name, e.message]
|
|
23
23
|
raise e
|
|
24
24
|
ensure
|
|
25
|
-
|
|
25
|
+
finish name, payload
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
+
# Send a start notification with +name+ and +payload+.
|
|
30
|
+
def start(name, payload)
|
|
31
|
+
@notifier.start name, @id, payload
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Send a finish notification with +name+ and +payload+.
|
|
35
|
+
def finish(name, payload)
|
|
36
|
+
@notifier.finish name, @id, payload
|
|
37
|
+
end
|
|
38
|
+
|
|
29
39
|
private
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
40
|
+
|
|
41
|
+
def unique_id
|
|
42
|
+
SecureRandom.hex(10)
|
|
43
|
+
end
|
|
33
44
|
end
|
|
34
45
|
|
|
35
46
|
class Event
|
|
36
|
-
attr_reader :name, :time, :
|
|
47
|
+
attr_reader :name, :time, :transaction_id, :payload, :children
|
|
48
|
+
attr_accessor :end
|
|
37
49
|
|
|
38
50
|
def initialize(name, start, ending, transaction_id, payload)
|
|
39
51
|
@name = name
|
|
@@ -41,12 +53,19 @@ module ActiveSupport
|
|
|
41
53
|
@time = start
|
|
42
54
|
@transaction_id = transaction_id
|
|
43
55
|
@end = ending
|
|
44
|
-
@
|
|
56
|
+
@children = []
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def duration
|
|
60
|
+
1000.0 * (self.end - time)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def <<(event)
|
|
64
|
+
@children << event
|
|
45
65
|
end
|
|
46
66
|
|
|
47
67
|
def parent_of?(event)
|
|
48
|
-
|
|
49
|
-
start <= 0 && (start + duration >= event.duration)
|
|
68
|
+
@children.include? event
|
|
50
69
|
end
|
|
51
70
|
end
|
|
52
71
|
end
|