activesupport 4.2.0 → 5.2.0

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.

Files changed (254) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +366 -232
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +4 -5
  5. data/lib/active_support.rb +17 -7
  6. data/lib/active_support/all.rb +5 -3
  7. data/lib/active_support/array_inquirer.rb +48 -0
  8. data/lib/active_support/backtrace_cleaner.rb +7 -5
  9. data/lib/active_support/benchmarkable.rb +6 -4
  10. data/lib/active_support/builder.rb +3 -1
  11. data/lib/active_support/cache.rb +271 -177
  12. data/lib/active_support/cache/file_store.rb +41 -35
  13. data/lib/active_support/cache/mem_cache_store.rb +97 -88
  14. data/lib/active_support/cache/memory_store.rb +27 -30
  15. data/lib/active_support/cache/null_store.rb +7 -8
  16. data/lib/active_support/cache/redis_cache_store.rb +454 -0
  17. data/lib/active_support/cache/strategy/local_cache.rb +67 -34
  18. data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
  19. data/lib/active_support/callbacks.rb +654 -560
  20. data/lib/active_support/concern.rb +5 -3
  21. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +17 -0
  22. data/lib/active_support/concurrency/share_lock.rb +227 -0
  23. data/lib/active_support/configurable.rb +8 -5
  24. data/lib/active_support/core_ext.rb +3 -1
  25. data/lib/active_support/core_ext/array.rb +9 -6
  26. data/lib/active_support/core_ext/array/access.rb +29 -1
  27. data/lib/active_support/core_ext/array/conversions.rb +22 -18
  28. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  29. data/lib/active_support/core_ext/array/grouping.rb +11 -18
  30. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  31. data/lib/active_support/core_ext/array/prepend_and_append.rb +5 -3
  32. data/lib/active_support/core_ext/array/wrap.rb +7 -4
  33. data/lib/active_support/core_ext/benchmark.rb +3 -1
  34. data/lib/active_support/core_ext/big_decimal.rb +3 -1
  35. data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
  36. data/lib/active_support/core_ext/class.rb +4 -3
  37. data/lib/active_support/core_ext/class/attribute.rb +41 -22
  38. data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
  39. data/lib/active_support/core_ext/class/subclasses.rb +20 -8
  40. data/lib/active_support/core_ext/date.rb +6 -4
  41. data/lib/active_support/core_ext/date/acts_like.rb +3 -1
  42. data/lib/active_support/core_ext/date/blank.rb +14 -0
  43. data/lib/active_support/core_ext/date/calculations.rb +11 -9
  44. data/lib/active_support/core_ext/date/conversions.rb +31 -23
  45. data/lib/active_support/core_ext/date/zones.rb +4 -2
  46. data/lib/active_support/core_ext/date_and_time/calculations.rb +179 -56
  47. data/lib/active_support/core_ext/date_and_time/compatibility.rb +16 -0
  48. data/lib/active_support/core_ext/date_and_time/zones.rb +12 -12
  49. data/lib/active_support/core_ext/date_time.rb +7 -4
  50. data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
  51. data/lib/active_support/core_ext/date_time/blank.rb +14 -0
  52. data/lib/active_support/core_ext/date_time/calculations.rb +58 -20
  53. data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
  54. data/lib/active_support/core_ext/date_time/conversions.rb +16 -12
  55. data/lib/active_support/core_ext/digest/uuid.rb +7 -5
  56. data/lib/active_support/core_ext/enumerable.rb +107 -28
  57. data/lib/active_support/core_ext/file.rb +3 -1
  58. data/lib/active_support/core_ext/file/atomic.rb +38 -31
  59. data/lib/active_support/core_ext/hash.rb +11 -9
  60. data/lib/active_support/core_ext/hash/compact.rb +24 -15
  61. data/lib/active_support/core_ext/hash/conversions.rb +63 -43
  62. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  63. data/lib/active_support/core_ext/hash/except.rb +11 -8
  64. data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
  65. data/lib/active_support/core_ext/hash/keys.rb +33 -27
  66. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  67. data/lib/active_support/core_ext/hash/slice.rb +8 -8
  68. data/lib/active_support/core_ext/hash/transform_values.rb +16 -7
  69. data/lib/active_support/core_ext/integer.rb +5 -3
  70. data/lib/active_support/core_ext/integer/inflections.rb +3 -1
  71. data/lib/active_support/core_ext/integer/multiple.rb +2 -0
  72. data/lib/active_support/core_ext/integer/time.rb +11 -33
  73. data/lib/active_support/core_ext/kernel.rb +6 -5
  74. data/lib/active_support/core_ext/kernel/agnostics.rb +2 -0
  75. data/lib/active_support/core_ext/kernel/concern.rb +5 -1
  76. data/lib/active_support/core_ext/kernel/reporting.rb +4 -83
  77. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  78. data/lib/active_support/core_ext/load_error.rb +3 -22
  79. data/lib/active_support/core_ext/marshal.rb +13 -10
  80. data/lib/active_support/core_ext/module.rb +14 -11
  81. data/lib/active_support/core_ext/module/aliasing.rb +6 -44
  82. data/lib/active_support/core_ext/module/anonymous.rb +12 -1
  83. data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
  84. data/lib/active_support/core_ext/module/attribute_accessors.rb +43 -40
  85. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +150 -0
  86. data/lib/active_support/core_ext/module/concerning.rb +11 -12
  87. data/lib/active_support/core_ext/module/delegation.rb +121 -39
  88. data/lib/active_support/core_ext/module/deprecation.rb +4 -2
  89. data/lib/active_support/core_ext/module/introspection.rb +9 -9
  90. data/lib/active_support/core_ext/module/reachable.rb +5 -2
  91. data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
  92. data/lib/active_support/core_ext/module/remove_method.rb +8 -3
  93. data/lib/active_support/core_ext/name_error.rb +22 -2
  94. data/lib/active_support/core_ext/numeric.rb +6 -3
  95. data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
  96. data/lib/active_support/core_ext/numeric/conversions.rb +79 -74
  97. data/lib/active_support/core_ext/numeric/inquiry.rb +28 -0
  98. data/lib/active_support/core_ext/numeric/time.rb +35 -38
  99. data/lib/active_support/core_ext/object.rb +14 -13
  100. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  101. data/lib/active_support/core_ext/object/blank.rb +29 -4
  102. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  103. data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
  104. data/lib/active_support/core_ext/object/duplicable.rb +98 -45
  105. data/lib/active_support/core_ext/object/inclusion.rb +5 -3
  106. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  107. data/lib/active_support/core_ext/object/json.rb +49 -19
  108. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  109. data/lib/active_support/core_ext/object/to_query.rb +6 -4
  110. data/lib/active_support/core_ext/object/try.rb +70 -22
  111. data/lib/active_support/core_ext/object/with_options.rb +16 -3
  112. data/lib/active_support/core_ext/range.rb +7 -4
  113. data/lib/active_support/core_ext/range/conversions.rb +27 -7
  114. data/lib/active_support/core_ext/range/each.rb +19 -17
  115. data/lib/active_support/core_ext/range/include_range.rb +21 -19
  116. data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
  117. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  118. data/lib/active_support/core_ext/regexp.rb +6 -0
  119. data/lib/active_support/core_ext/securerandom.rb +25 -0
  120. data/lib/active_support/core_ext/string.rb +15 -13
  121. data/lib/active_support/core_ext/string/access.rb +9 -7
  122. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  123. data/lib/active_support/core_ext/string/conversions.rb +8 -5
  124. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  125. data/lib/active_support/core_ext/string/filters.rb +10 -8
  126. data/lib/active_support/core_ext/string/indent.rb +6 -4
  127. data/lib/active_support/core_ext/string/inflections.rb +61 -24
  128. data/lib/active_support/core_ext/string/inquiry.rb +3 -1
  129. data/lib/active_support/core_ext/string/multibyte.rb +15 -7
  130. data/lib/active_support/core_ext/string/output_safety.rb +35 -35
  131. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
  132. data/lib/active_support/core_ext/string/strip.rb +4 -5
  133. data/lib/active_support/core_ext/string/zones.rb +4 -2
  134. data/lib/active_support/core_ext/time.rb +7 -5
  135. data/lib/active_support/core_ext/time/acts_like.rb +3 -1
  136. data/lib/active_support/core_ext/time/calculations.rb +101 -51
  137. data/lib/active_support/core_ext/time/compatibility.rb +16 -0
  138. data/lib/active_support/core_ext/time/conversions.rb +20 -13
  139. data/lib/active_support/core_ext/time/zones.rb +41 -7
  140. data/lib/active_support/core_ext/uri.rb +5 -4
  141. data/lib/active_support/current_attributes.rb +195 -0
  142. data/lib/active_support/dependencies.rb +143 -160
  143. data/lib/active_support/dependencies/autoload.rb +2 -0
  144. data/lib/active_support/dependencies/interlock.rb +57 -0
  145. data/lib/active_support/deprecation.rb +12 -9
  146. data/lib/active_support/deprecation/behaviors.rb +41 -12
  147. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  148. data/lib/active_support/deprecation/instance_delegator.rb +17 -2
  149. data/lib/active_support/deprecation/method_wrappers.rb +54 -21
  150. data/lib/active_support/deprecation/proxy_wrappers.rb +56 -28
  151. data/lib/active_support/deprecation/reporting.rb +32 -12
  152. data/lib/active_support/descendants_tracker.rb +2 -0
  153. data/lib/active_support/digest.rb +20 -0
  154. data/lib/active_support/duration.rb +326 -30
  155. data/lib/active_support/duration/iso8601_parser.rb +125 -0
  156. data/lib/active_support/duration/iso8601_serializer.rb +55 -0
  157. data/lib/active_support/encrypted_configuration.rb +49 -0
  158. data/lib/active_support/encrypted_file.rb +99 -0
  159. data/lib/active_support/evented_file_update_checker.rb +205 -0
  160. data/lib/active_support/execution_wrapper.rb +128 -0
  161. data/lib/active_support/executor.rb +8 -0
  162. data/lib/active_support/file_update_checker.rb +63 -37
  163. data/lib/active_support/gem_version.rb +4 -2
  164. data/lib/active_support/gzip.rb +7 -5
  165. data/lib/active_support/hash_with_indifferent_access.rb +130 -30
  166. data/lib/active_support/i18n.rb +8 -6
  167. data/lib/active_support/i18n_railtie.rb +34 -14
  168. data/lib/active_support/inflections.rb +13 -11
  169. data/lib/active_support/inflector.rb +7 -5
  170. data/lib/active_support/inflector/inflections.rb +61 -12
  171. data/lib/active_support/inflector/methods.rb +161 -136
  172. data/lib/active_support/inflector/transliterate.rb +48 -27
  173. data/lib/active_support/json.rb +4 -2
  174. data/lib/active_support/json/decoding.rb +16 -13
  175. data/lib/active_support/json/encoding.rb +15 -57
  176. data/lib/active_support/key_generator.rb +25 -25
  177. data/lib/active_support/lazy_load_hooks.rb +50 -20
  178. data/lib/active_support/locale/en.yml +2 -0
  179. data/lib/active_support/log_subscriber.rb +13 -10
  180. data/lib/active_support/log_subscriber/test_helper.rb +14 -12
  181. data/lib/active_support/logger.rb +54 -3
  182. data/lib/active_support/logger_silence.rb +12 -7
  183. data/lib/active_support/logger_thread_safe_level.rb +33 -0
  184. data/lib/active_support/message_encryptor.rb +173 -51
  185. data/lib/active_support/message_verifier.rb +150 -17
  186. data/lib/active_support/messages/metadata.rb +71 -0
  187. data/lib/active_support/messages/rotation_configuration.rb +22 -0
  188. data/lib/active_support/messages/rotator.rb +56 -0
  189. data/lib/active_support/multibyte.rb +4 -2
  190. data/lib/active_support/multibyte/chars.rb +37 -24
  191. data/lib/active_support/multibyte/unicode.rb +100 -96
  192. data/lib/active_support/notifications.rb +11 -7
  193. data/lib/active_support/notifications/fanout.rb +10 -8
  194. data/lib/active_support/notifications/instrumenter.rb +27 -7
  195. data/lib/active_support/number_helper.rb +94 -68
  196. data/lib/active_support/number_helper/number_converter.rb +13 -11
  197. data/lib/active_support/number_helper/number_to_currency_converter.rb +9 -9
  198. data/lib/active_support/number_helper/number_to_delimited_converter.rb +9 -3
  199. data/lib/active_support/number_helper/number_to_human_converter.rb +11 -9
  200. data/lib/active_support/number_helper/number_to_human_size_converter.rb +9 -8
  201. data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
  202. data/lib/active_support/number_helper/number_to_phone_converter.rb +13 -4
  203. data/lib/active_support/number_helper/number_to_rounded_converter.rb +23 -56
  204. data/lib/active_support/number_helper/rounding_helper.rb +66 -0
  205. data/lib/active_support/option_merger.rb +3 -1
  206. data/lib/active_support/ordered_hash.rb +6 -4
  207. data/lib/active_support/ordered_options.rb +22 -4
  208. data/lib/active_support/per_thread_registry.rb +13 -6
  209. data/lib/active_support/proxy_object.rb +2 -0
  210. data/lib/active_support/rails.rb +16 -8
  211. data/lib/active_support/railtie.rb +43 -9
  212. data/lib/active_support/reloader.rb +131 -0
  213. data/lib/active_support/rescuable.rb +108 -53
  214. data/lib/active_support/security_utils.rb +17 -6
  215. data/lib/active_support/string_inquirer.rb +11 -3
  216. data/lib/active_support/subscriber.rb +15 -14
  217. data/lib/active_support/tagged_logging.rb +14 -11
  218. data/lib/active_support/test_case.rb +18 -46
  219. data/lib/active_support/testing/assertions.rb +137 -20
  220. data/lib/active_support/testing/autorun.rb +4 -2
  221. data/lib/active_support/testing/constant_lookup.rb +2 -1
  222. data/lib/active_support/testing/declarative.rb +3 -1
  223. data/lib/active_support/testing/deprecation.rb +14 -10
  224. data/lib/active_support/testing/file_fixtures.rb +36 -0
  225. data/lib/active_support/testing/isolation.rb +34 -25
  226. data/lib/active_support/testing/method_call_assertions.rb +43 -0
  227. data/lib/active_support/testing/setup_and_teardown.rb +12 -3
  228. data/lib/active_support/testing/stream.rb +44 -0
  229. data/lib/active_support/testing/tagged_logging.rb +3 -1
  230. data/lib/active_support/testing/time_helpers.rb +96 -27
  231. data/lib/active_support/time.rb +14 -12
  232. data/lib/active_support/time_with_zone.rb +195 -53
  233. data/lib/active_support/values/time_zone.rb +200 -61
  234. data/lib/active_support/values/unicode_tables.dat +0 -0
  235. data/lib/active_support/version.rb +3 -1
  236. data/lib/active_support/xml_mini.rb +69 -51
  237. data/lib/active_support/xml_mini/jdom.rb +116 -113
  238. data/lib/active_support/xml_mini/libxml.rb +17 -16
  239. data/lib/active_support/xml_mini/libxmlsax.rb +16 -18
  240. data/lib/active_support/xml_mini/nokogiri.rb +15 -15
  241. data/lib/active_support/xml_mini/nokogirisax.rb +15 -16
  242. data/lib/active_support/xml_mini/rexml.rb +17 -16
  243. metadata +55 -43
  244. data/lib/active_support/concurrency/latch.rb +0 -27
  245. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -14
  246. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  247. data/lib/active_support/core_ext/date_time/zones.rb +0 -6
  248. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  249. data/lib/active_support/core_ext/module/method_transplanting.rb +0 -11
  250. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  251. data/lib/active_support/core_ext/object/itself.rb +0 -15
  252. data/lib/active_support/core_ext/struct.rb +0 -6
  253. data/lib/active_support/core_ext/thread.rb +0 -86
  254. data/lib/active_support/core_ext/time/marshal.rb +0 -30
@@ -1,8 +1,8 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  module ActiveSupport
3
4
  module Multibyte
4
5
  module Unicode
5
-
6
6
  extend self
7
7
 
8
8
  # A list of all available normalization forms.
@@ -11,7 +11,7 @@ module ActiveSupport
11
11
  NORMALIZATION_FORMS = [:c, :kc, :d, :kd]
12
12
 
13
13
  # The Unicode version that is supported by the implementation
14
- UNICODE_VERSION = '7.0.0'
14
+ UNICODE_VERSION = "9.0.0"
15
15
 
16
16
  # The default normalization used for operations that require
17
17
  # normalization. It can be set to any of the normalizations
@@ -32,36 +32,6 @@ module ActiveSupport
32
32
  HANGUL_NCOUNT = HANGUL_VCOUNT * HANGUL_TCOUNT
33
33
  HANGUL_SCOUNT = 11172
34
34
  HANGUL_SLAST = HANGUL_SBASE + HANGUL_SCOUNT
35
- HANGUL_JAMO_FIRST = 0x1100
36
- HANGUL_JAMO_LAST = 0x11FF
37
-
38
- # All the unicode whitespace
39
- WHITESPACE = [
40
- (0x0009..0x000D).to_a, # White_Space # Cc [5] <control-0009>..<control-000D>
41
- 0x0020, # White_Space # Zs SPACE
42
- 0x0085, # White_Space # Cc <control-0085>
43
- 0x00A0, # White_Space # Zs NO-BREAK SPACE
44
- 0x1680, # White_Space # Zs OGHAM SPACE MARK
45
- (0x2000..0x200A).to_a, # White_Space # Zs [11] EN QUAD..HAIR SPACE
46
- 0x2028, # White_Space # Zl LINE SEPARATOR
47
- 0x2029, # White_Space # Zp PARAGRAPH SEPARATOR
48
- 0x202F, # White_Space # Zs NARROW NO-BREAK SPACE
49
- 0x205F, # White_Space # Zs MEDIUM MATHEMATICAL SPACE
50
- 0x3000, # White_Space # Zs IDEOGRAPHIC SPACE
51
- ].flatten.freeze
52
-
53
- # BOM (byte order mark) can also be seen as whitespace, it's a
54
- # non-rendering character used to distinguish between little and big
55
- # endian. This is not an issue in utf-8, so it must be ignored.
56
- LEADERS_AND_TRAILERS = WHITESPACE + [65279] # ZERO-WIDTH NO-BREAK SPACE aka BOM
57
-
58
- # Returns a regular expression pattern that matches the passed Unicode
59
- # codepoints.
60
- def self.codepoints_to_pattern(array_of_codepoints) #:nodoc:
61
- array_of_codepoints.collect{ |e| [e].pack 'U*' }.join('|')
62
- end
63
- TRAILERS_PAT = /(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+\Z/u
64
- LEADERS_PAT = /\A(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+/u
65
35
 
66
36
  # Detect whether the codepoint is in a certain character class. Returns
67
37
  # +true+ when it's in the specified character class and +false+ otherwise.
@@ -84,24 +54,59 @@ module ActiveSupport
84
54
  pos = 0
85
55
  marker = 0
86
56
  eoc = codepoints.length
87
- while(pos < eoc)
57
+ while (pos < eoc)
88
58
  pos += 1
89
- previous = codepoints[pos-1]
59
+ previous = codepoints[pos - 1]
90
60
  current = codepoints[pos]
91
- if (
92
- # CR X LF
93
- ( previous == database.boundary[:cr] and current == database.boundary[:lf] ) or
94
- # L X (L|V|LV|LVT)
95
- ( database.boundary[:l] === previous and in_char_class?(current, [:l,:v,:lv,:lvt]) ) or
96
- # (LV|V) X (V|T)
97
- ( in_char_class?(previous, [:lv,:v]) and in_char_class?(current, [:v,:t]) ) or
98
- # (LVT|T) X (T)
99
- ( in_char_class?(previous, [:lvt,:t]) and database.boundary[:t] === current ) or
100
- # X Extend
101
- (database.boundary[:extend] === current)
102
- )
103
- else
104
- unpacked << codepoints[marker..pos-1]
61
+
62
+ # See http://unicode.org/reports/tr29/#Grapheme_Cluster_Boundary_Rules
63
+ should_break =
64
+ if pos == eoc
65
+ true
66
+ # GB3. CR X LF
67
+ elsif previous == database.boundary[:cr] && current == database.boundary[:lf]
68
+ false
69
+ # GB4. (Control|CR|LF) ÷
70
+ elsif previous && in_char_class?(previous, [:control, :cr, :lf])
71
+ true
72
+ # GB5. ÷ (Control|CR|LF)
73
+ elsif in_char_class?(current, [:control, :cr, :lf])
74
+ true
75
+ # GB6. L X (L|V|LV|LVT)
76
+ elsif database.boundary[:l] === previous && in_char_class?(current, [:l, :v, :lv, :lvt])
77
+ false
78
+ # GB7. (LV|V) X (V|T)
79
+ elsif in_char_class?(previous, [:lv, :v]) && in_char_class?(current, [:v, :t])
80
+ false
81
+ # GB8. (LVT|T) X (T)
82
+ elsif in_char_class?(previous, [:lvt, :t]) && database.boundary[:t] === current
83
+ false
84
+ # GB9. X (Extend | ZWJ)
85
+ elsif in_char_class?(current, [:extend, :zwj])
86
+ false
87
+ # GB9a. X SpacingMark
88
+ elsif database.boundary[:spacingmark] === current
89
+ false
90
+ # GB9b. Prepend X
91
+ elsif database.boundary[:prepend] === previous
92
+ false
93
+ # GB10. (E_Base | EBG) Extend* X E_Modifier
94
+ elsif (marker...pos).any? { |i| in_char_class?(codepoints[i], [:e_base, :e_base_gaz]) && codepoints[i + 1...pos].all? { |c| database.boundary[:extend] === c } } && database.boundary[:e_modifier] === current
95
+ false
96
+ # GB11. ZWJ X (Glue_After_Zwj | EBG)
97
+ elsif database.boundary[:zwj] === previous && in_char_class?(current, [:glue_after_zwj, :e_base_gaz])
98
+ false
99
+ # GB12. ^ (RI RI)* RI X RI
100
+ # GB13. [^RI] (RI RI)* RI X RI
101
+ elsif codepoints[marker..pos].all? { |c| database.boundary[:regional_indicator] === c } && codepoints[marker..pos].count { |c| database.boundary[:regional_indicator] === c }.even?
102
+ false
103
+ # GB999. Any ÷ Any
104
+ else
105
+ true
106
+ end
107
+
108
+ if should_break
109
+ unpacked << codepoints[marker..pos - 1]
105
110
  marker = pos
106
111
  end
107
112
  end
@@ -112,17 +117,17 @@ module ActiveSupport
112
117
  #
113
118
  # Unicode.pack_graphemes(Unicode.unpack_graphemes('क्षि')) # => 'क्षि'
114
119
  def pack_graphemes(unpacked)
115
- unpacked.flatten.pack('U*')
120
+ unpacked.flatten.pack("U*")
116
121
  end
117
122
 
118
123
  # Re-order codepoints so the string becomes canonical.
119
124
  def reorder_characters(codepoints)
120
- length = codepoints.length- 1
125
+ length = codepoints.length - 1
121
126
  pos = 0
122
127
  while pos < length do
123
- cp1, cp2 = database.codepoints[codepoints[pos]], database.codepoints[codepoints[pos+1]]
128
+ cp1, cp2 = database.codepoints[codepoints[pos]], database.codepoints[codepoints[pos + 1]]
124
129
  if (cp1.combining_class > cp2.combining_class) && (cp2.combining_class > 0)
125
- codepoints[pos..pos+1] = cp2.code, cp1.code
130
+ codepoints[pos..pos + 1] = cp2.code, cp1.code
126
131
  pos += (pos > 0 ? -1 : 1)
127
132
  else
128
133
  pos += 1
@@ -135,7 +140,7 @@ module ActiveSupport
135
140
  def decompose(type, codepoints)
136
141
  codepoints.inject([]) do |decomposed, cp|
137
142
  # if it's a hangul syllable starter character
138
- if HANGUL_SBASE <= cp and cp < HANGUL_SLAST
143
+ if HANGUL_SBASE <= cp && cp < HANGUL_SLAST
139
144
  sindex = cp - HANGUL_SBASE
140
145
  ncp = [] # new codepoints
141
146
  ncp << HANGUL_LBASE + sindex / HANGUL_NCOUNT
@@ -144,7 +149,7 @@ module ActiveSupport
144
149
  ncp << (HANGUL_TBASE + tindex) unless tindex == 0
145
150
  decomposed.concat ncp
146
151
  # if the codepoint is decomposable in with the current decomposition type
147
- elsif (ncp = database.codepoints[cp].decomp_mapping) and (!database.codepoints[cp].decomp_type || type == :compatibility)
152
+ elsif (ncp = database.codepoints[cp].decomp_mapping) && (!database.codepoints[cp].decomp_type || type == :compatibility)
148
153
  decomposed.concat decompose(type, ncp.dup)
149
154
  else
150
155
  decomposed << cp
@@ -163,11 +168,11 @@ module ActiveSupport
163
168
  pos += 1
164
169
  lindex = starter_char - HANGUL_LBASE
165
170
  # -- Hangul
166
- if 0 <= lindex and lindex < HANGUL_LCOUNT
167
- vindex = codepoints[starter_pos+1] - HANGUL_VBASE rescue vindex = -1
168
- if 0 <= vindex and vindex < HANGUL_VCOUNT
169
- tindex = codepoints[starter_pos+2] - HANGUL_TBASE rescue tindex = -1
170
- if 0 <= tindex and tindex < HANGUL_TCOUNT
171
+ if 0 <= lindex && lindex < HANGUL_LCOUNT
172
+ vindex = codepoints[starter_pos + 1] - HANGUL_VBASE rescue vindex = -1
173
+ if 0 <= vindex && vindex < HANGUL_VCOUNT
174
+ tindex = codepoints[starter_pos + 2] - HANGUL_TBASE rescue tindex = -1
175
+ if 0 <= tindex && tindex < HANGUL_TCOUNT
171
176
  j = starter_pos + 2
172
177
  eoa -= 2
173
178
  else
@@ -211,9 +216,8 @@ module ActiveSupport
211
216
  codepoints
212
217
  end
213
218
 
214
- # Ruby >= 2.1 has String#scrub, which is faster than the workaround used for < 2.1.
215
219
  # Rubinius' String#scrub, however, doesn't support ASCII-incompatible chars.
216
- if '<3'.respond_to?(:scrub) && !defined?(Rubinius)
220
+ if !defined?(Rubinius)
217
221
  # Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent
218
222
  # resulting in a valid UTF-8 string.
219
223
  #
@@ -236,7 +240,7 @@ module ActiveSupport
236
240
  reader = Encoding::Converter.new(Encoding::UTF_8, Encoding::UTF_16LE)
237
241
 
238
242
  source = string.dup
239
- out = ''.force_encoding(Encoding::UTF_16LE)
243
+ out = "".force_encoding(Encoding::UTF_16LE)
240
244
 
241
245
  loop do
242
246
  reader.primitive_convert(source, out)
@@ -258,23 +262,23 @@ module ActiveSupport
258
262
  # * <tt>string</tt> - The string to perform normalization on.
259
263
  # * <tt>form</tt> - The form you want to normalize in. Should be one of
260
264
  # the following: <tt>:c</tt>, <tt>:kc</tt>, <tt>:d</tt>, or <tt>:kd</tt>.
261
- # Default is ActiveSupport::Multibyte.default_normalization_form.
262
- def normalize(string, form=nil)
265
+ # Default is ActiveSupport::Multibyte::Unicode.default_normalization_form.
266
+ def normalize(string, form = nil)
263
267
  form ||= @default_normalization_form
264
268
  # See http://www.unicode.org/reports/tr15, Table 1
265
269
  codepoints = string.codepoints.to_a
266
270
  case form
267
- when :d
268
- reorder_characters(decompose(:canonical, codepoints))
269
- when :c
270
- compose(reorder_characters(decompose(:canonical, codepoints)))
271
- when :kd
272
- reorder_characters(decompose(:compatibility, codepoints))
273
- when :kc
274
- compose(reorder_characters(decompose(:compatibility, codepoints)))
275
- else
276
- raise ArgumentError, "#{form} is not a valid normalization variant", caller
277
- end.pack('U*')
271
+ when :d
272
+ reorder_characters(decompose(:canonical, codepoints))
273
+ when :c
274
+ compose(reorder_characters(decompose(:canonical, codepoints)))
275
+ when :kd
276
+ reorder_characters(decompose(:compatibility, codepoints))
277
+ when :kc
278
+ compose(reorder_characters(decompose(:compatibility, codepoints)))
279
+ else
280
+ raise ArgumentError, "#{form} is not a valid normalization variant", caller
281
+ end.pack("U*".freeze)
278
282
  end
279
283
 
280
284
  def downcase(string)
@@ -333,13 +337,13 @@ module ActiveSupport
333
337
  # UnicodeDatabase.
334
338
  def load
335
339
  begin
336
- @codepoints, @composition_exclusion, @composition_map, @boundary, @cp1252 = File.open(self.class.filename, 'rb') { |f| Marshal.load f.read }
340
+ @codepoints, @composition_exclusion, @composition_map, @boundary, @cp1252 = File.open(self.class.filename, "rb") { |f| Marshal.load f.read }
337
341
  rescue => e
338
342
  raise IOError.new("Couldn't load the Unicode tables for UTF8Handler (#{e.message}), ActiveSupport::Multibyte is unusable")
339
343
  end
340
344
 
341
345
  # Redefine the === method so we can write shorter rules for grapheme cluster breaks
342
- @boundary.each do |k,_|
346
+ @boundary.each_key do |k|
343
347
  @boundary[k].instance_eval do
344
348
  def ===(other)
345
349
  detect { |i| i === other } ? true : false
@@ -355,7 +359,7 @@ module ActiveSupport
355
359
 
356
360
  # Returns the directory in which the data files are stored.
357
361
  def self.dirname
358
- File.dirname(__FILE__) + '/../values/'
362
+ File.expand_path("../values", __dir__)
359
363
  end
360
364
 
361
365
  # Returns the filename for the data file for this version.
@@ -366,25 +370,25 @@ module ActiveSupport
366
370
 
367
371
  private
368
372
 
369
- def apply_mapping(string, mapping) #:nodoc:
370
- database.codepoints
371
- string.each_codepoint.map do |codepoint|
372
- cp = database.codepoints[codepoint]
373
- if cp and (ncp = cp.send(mapping)) and ncp > 0
374
- ncp
375
- else
376
- codepoint
377
- end
378
- end.pack('U*')
379
- end
373
+ def apply_mapping(string, mapping)
374
+ database.codepoints
375
+ string.each_codepoint.map do |codepoint|
376
+ cp = database.codepoints[codepoint]
377
+ if cp && (ncp = cp.send(mapping)) && ncp > 0
378
+ ncp
379
+ else
380
+ codepoint
381
+ end
382
+ end.pack("U*")
383
+ end
380
384
 
381
- def recode_windows1252_chars(string)
382
- string.encode(Encoding::UTF_8, Encoding::Windows_1252, invalid: :replace, undef: :replace)
383
- end
385
+ def recode_windows1252_chars(string)
386
+ string.encode(Encoding::UTF_8, Encoding::Windows_1252, invalid: :replace, undef: :replace)
387
+ end
384
388
 
385
- def database
386
- @database ||= UnicodeDatabase.new
387
- end
389
+ def database
390
+ @database ||= UnicodeDatabase.new
391
+ end
388
392
  end
389
393
  end
390
394
  end
@@ -1,6 +1,8 @@
1
- require 'active_support/notifications/instrumenter'
2
- require 'active_support/notifications/fanout'
3
- require 'active_support/per_thread_registry'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/notifications/instrumenter"
4
+ require "active_support/notifications/fanout"
5
+ require "active_support/per_thread_registry"
4
6
 
5
7
  module ActiveSupport
6
8
  # = Notifications
@@ -13,7 +15,7 @@ module ActiveSupport
13
15
  # To instrument an event you just need to do:
14
16
  #
15
17
  # ActiveSupport::Notifications.instrument('render', extra: :information) do
16
- # render text: 'Foo'
18
+ # render plain: 'Foo'
17
19
  # end
18
20
  #
19
21
  # That first executes the block and then notifies all subscribers once done.
@@ -48,7 +50,7 @@ module ActiveSupport
48
50
  # The block is saved and will be called whenever someone instruments "render":
49
51
  #
50
52
  # ActiveSupport::Notifications.instrument('render', extra: :information) do
51
- # render text: 'Foo'
53
+ # render plain: 'Foo'
52
54
  # end
53
55
  #
54
56
  # event = events.first
@@ -64,13 +66,15 @@ module ActiveSupport
64
66
  # If an exception happens during that particular instrumentation the payload will
65
67
  # have a key <tt>:exception</tt> with an array of two elements as value: a string with
66
68
  # the name of the exception class, and the exception message.
69
+ # The <tt>:exception_object</tt> key of the payload will have the exception
70
+ # itself as the value.
67
71
  #
68
72
  # As the previous example depicts, the class <tt>ActiveSupport::Notifications::Event</tt>
69
73
  # is able to take the arguments as they come and provide an object-oriented
70
74
  # interface to that data.
71
75
  #
72
- # It is also possible to pass an object as the second parameter passed to the
73
- # <tt>subscribe</tt> method instead of a block:
76
+ # It is also possible to pass an object which responds to <tt>call</tt> method
77
+ # as the second parameter to the <tt>subscribe</tt> method instead of a block:
74
78
  #
75
79
  # module ActionController
76
80
  # class PageRequest
@@ -1,5 +1,7 @@
1
- require 'mutex_m'
2
- require 'thread_safe'
1
+ # frozen_string_literal: true
2
+
3
+ require "mutex_m"
4
+ require "concurrent/map"
3
5
 
4
6
  module ActiveSupport
5
7
  module Notifications
@@ -12,7 +14,7 @@ module ActiveSupport
12
14
 
13
15
  def initialize
14
16
  @subscribers = []
15
- @listeners_for = ThreadSafe::Cache.new
17
+ @listeners_for = Concurrent::Map.new
16
18
  super
17
19
  end
18
20
 
@@ -42,8 +44,8 @@ module ActiveSupport
42
44
  listeners_for(name).each { |s| s.start(name, id, payload) }
43
45
  end
44
46
 
45
- def finish(name, id, payload)
46
- listeners_for(name).each { |s| s.finish(name, id, payload) }
47
+ def finish(name, id, payload, listeners = listeners_for(name))
48
+ listeners.each { |s| s.finish(name, id, payload) }
47
49
  end
48
50
 
49
51
  def publish(name, *args)
@@ -51,7 +53,7 @@ module ActiveSupport
51
53
  end
52
54
 
53
55
  def listeners_for(name)
54
- # this is correctly done double-checked locking (ThreadSafe::Cache's lookups have volatile semantics)
56
+ # this is correctly done double-checked locking (Concurrent::Map's lookups have volatile semantics)
55
57
  @listeners_for[name] || synchronize do
56
58
  # use synchronisation when accessing @subscribers
57
59
  @listeners_for[name] ||= @subscribers.select { |s| s.subscribed_to?(name) }
@@ -68,7 +70,7 @@ module ActiveSupport
68
70
 
69
71
  module Subscribers # :nodoc:
70
72
  def self.new(pattern, listener)
71
- if listener.respond_to?(:start) and listener.respond_to?(:finish)
73
+ if listener.respond_to?(:start) && listener.respond_to?(:finish)
72
74
  subscriber = Evented.new pattern, listener
73
75
  else
74
76
  subscriber = Timed.new pattern, listener
@@ -111,7 +113,7 @@ module ActiveSupport
111
113
  end
112
114
  end
113
115
 
114
- class Timed < Evented
116
+ class Timed < Evented # :nodoc:
115
117
  def publish(name, *args)
116
118
  @delegate.call name, *args
117
119
  end
@@ -1,4 +1,6 @@
1
- require 'securerandom'
1
+ # frozen_string_literal: true
2
+
3
+ require "securerandom"
2
4
 
3
5
  module ActiveSupport
4
6
  module Notifications
@@ -14,15 +16,17 @@ module ActiveSupport
14
16
  # Instrument the given block by measuring the time taken to execute it
15
17
  # and publish it. Notice that events get sent even if an error occurs
16
18
  # in the passed-in block.
17
- def instrument(name, payload={})
18
- start name, payload
19
+ def instrument(name, payload = {})
20
+ # some of the listeners might have state
21
+ listeners_state = start name, payload
19
22
  begin
20
23
  yield payload
21
24
  rescue Exception => e
22
25
  payload[:exception] = [e.class.name, e.message]
26
+ payload[:exception_object] = e
23
27
  raise e
24
28
  ensure
25
- finish name, payload
29
+ finish_with_state listeners_state, name, payload
26
30
  end
27
31
  end
28
32
 
@@ -36,11 +40,15 @@ module ActiveSupport
36
40
  @notifier.finish name, @id, payload
37
41
  end
38
42
 
43
+ def finish_with_state(listeners_state, name, payload)
44
+ @notifier.finish name, @id, payload, listeners_state
45
+ end
46
+
39
47
  private
40
48
 
41
- def unique_id
42
- SecureRandom.hex(10)
43
- end
49
+ def unique_id
50
+ SecureRandom.hex(10)
51
+ end
44
52
  end
45
53
 
46
54
  class Event
@@ -57,6 +65,18 @@ module ActiveSupport
57
65
  @duration = nil
58
66
  end
59
67
 
68
+ # Returns the difference in milliseconds between when the execution of the
69
+ # event started and when it ended.
70
+ #
71
+ # ActiveSupport::Notifications.subscribe('wait') do |*args|
72
+ # @event = ActiveSupport::Notifications::Event.new(*args)
73
+ # end
74
+ #
75
+ # ActiveSupport::Notifications.instrument('wait') do
76
+ # sleep 1
77
+ # end
78
+ #
79
+ # @event.duration # => 1000.138
60
80
  def duration
61
81
  @duration ||= 1000.0 * (self.end - time)
62
82
  end