activesupport 5.0.7.1

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 (236) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1013 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +39 -0
  5. data/lib/active_support.rb +99 -0
  6. data/lib/active_support/all.rb +3 -0
  7. data/lib/active_support/array_inquirer.rb +44 -0
  8. data/lib/active_support/backtrace_cleaner.rb +103 -0
  9. data/lib/active_support/benchmarkable.rb +49 -0
  10. data/lib/active_support/builder.rb +6 -0
  11. data/lib/active_support/cache.rb +701 -0
  12. data/lib/active_support/cache/file_store.rb +204 -0
  13. data/lib/active_support/cache/mem_cache_store.rb +207 -0
  14. data/lib/active_support/cache/memory_store.rb +167 -0
  15. data/lib/active_support/cache/null_store.rb +41 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +172 -0
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +44 -0
  18. data/lib/active_support/callbacks.rb +791 -0
  19. data/lib/active_support/concern.rb +142 -0
  20. data/lib/active_support/concurrency/latch.rb +26 -0
  21. data/lib/active_support/concurrency/share_lock.rb +226 -0
  22. data/lib/active_support/configurable.rb +148 -0
  23. data/lib/active_support/core_ext.rb +4 -0
  24. data/lib/active_support/core_ext/array.rb +7 -0
  25. data/lib/active_support/core_ext/array/access.rb +90 -0
  26. data/lib/active_support/core_ext/array/conversions.rb +211 -0
  27. data/lib/active_support/core_ext/array/extract_options.rb +29 -0
  28. data/lib/active_support/core_ext/array/grouping.rb +107 -0
  29. data/lib/active_support/core_ext/array/inquiry.rb +17 -0
  30. data/lib/active_support/core_ext/array/prepend_and_append.rb +7 -0
  31. data/lib/active_support/core_ext/array/wrap.rb +46 -0
  32. data/lib/active_support/core_ext/benchmark.rb +14 -0
  33. data/lib/active_support/core_ext/big_decimal.rb +1 -0
  34. data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
  35. data/lib/active_support/core_ext/class.rb +2 -0
  36. data/lib/active_support/core_ext/class/attribute.rb +128 -0
  37. data/lib/active_support/core_ext/class/attribute_accessors.rb +4 -0
  38. data/lib/active_support/core_ext/class/subclasses.rb +41 -0
  39. data/lib/active_support/core_ext/date.rb +5 -0
  40. data/lib/active_support/core_ext/date/acts_like.rb +8 -0
  41. data/lib/active_support/core_ext/date/blank.rb +12 -0
  42. data/lib/active_support/core_ext/date/calculations.rb +143 -0
  43. data/lib/active_support/core_ext/date/conversions.rb +95 -0
  44. data/lib/active_support/core_ext/date/zones.rb +6 -0
  45. data/lib/active_support/core_ext/date_and_time/calculations.rb +335 -0
  46. data/lib/active_support/core_ext/date_and_time/compatibility.rb +14 -0
  47. data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
  48. data/lib/active_support/core_ext/date_time.rb +5 -0
  49. data/lib/active_support/core_ext/date_time/acts_like.rb +14 -0
  50. data/lib/active_support/core_ext/date_time/blank.rb +12 -0
  51. data/lib/active_support/core_ext/date_time/calculations.rb +199 -0
  52. data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
  53. data/lib/active_support/core_ext/date_time/conversions.rb +105 -0
  54. data/lib/active_support/core_ext/digest/uuid.rb +51 -0
  55. data/lib/active_support/core_ext/enumerable.rb +146 -0
  56. data/lib/active_support/core_ext/file.rb +1 -0
  57. data/lib/active_support/core_ext/file/atomic.rb +68 -0
  58. data/lib/active_support/core_ext/hash.rb +9 -0
  59. data/lib/active_support/core_ext/hash/compact.rb +24 -0
  60. data/lib/active_support/core_ext/hash/conversions.rb +262 -0
  61. data/lib/active_support/core_ext/hash/deep_merge.rb +38 -0
  62. data/lib/active_support/core_ext/hash/except.rb +22 -0
  63. data/lib/active_support/core_ext/hash/indifferent_access.rb +23 -0
  64. data/lib/active_support/core_ext/hash/keys.rb +170 -0
  65. data/lib/active_support/core_ext/hash/reverse_merge.rb +22 -0
  66. data/lib/active_support/core_ext/hash/slice.rb +48 -0
  67. data/lib/active_support/core_ext/hash/transform_values.rb +29 -0
  68. data/lib/active_support/core_ext/integer.rb +3 -0
  69. data/lib/active_support/core_ext/integer/inflections.rb +29 -0
  70. data/lib/active_support/core_ext/integer/multiple.rb +10 -0
  71. data/lib/active_support/core_ext/integer/time.rb +29 -0
  72. data/lib/active_support/core_ext/kernel.rb +4 -0
  73. data/lib/active_support/core_ext/kernel/agnostics.rb +11 -0
  74. data/lib/active_support/core_ext/kernel/concern.rb +12 -0
  75. data/lib/active_support/core_ext/kernel/debugger.rb +3 -0
  76. data/lib/active_support/core_ext/kernel/reporting.rb +43 -0
  77. data/lib/active_support/core_ext/kernel/singleton_class.rb +6 -0
  78. data/lib/active_support/core_ext/load_error.rb +31 -0
  79. data/lib/active_support/core_ext/marshal.rb +22 -0
  80. data/lib/active_support/core_ext/module.rb +12 -0
  81. data/lib/active_support/core_ext/module/aliasing.rb +74 -0
  82. data/lib/active_support/core_ext/module/anonymous.rb +28 -0
  83. data/lib/active_support/core_ext/module/attr_internal.rb +36 -0
  84. data/lib/active_support/core_ext/module/attribute_accessors.rb +212 -0
  85. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
  86. data/lib/active_support/core_ext/module/concerning.rb +135 -0
  87. data/lib/active_support/core_ext/module/delegation.rb +216 -0
  88. data/lib/active_support/core_ext/module/deprecation.rb +23 -0
  89. data/lib/active_support/core_ext/module/introspection.rb +68 -0
  90. data/lib/active_support/core_ext/module/method_transplanting.rb +3 -0
  91. data/lib/active_support/core_ext/module/qualified_const.rb +70 -0
  92. data/lib/active_support/core_ext/module/reachable.rb +8 -0
  93. data/lib/active_support/core_ext/module/remove_method.rb +35 -0
  94. data/lib/active_support/core_ext/name_error.rb +31 -0
  95. data/lib/active_support/core_ext/numeric.rb +4 -0
  96. data/lib/active_support/core_ext/numeric/bytes.rb +64 -0
  97. data/lib/active_support/core_ext/numeric/conversions.rb +144 -0
  98. data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
  99. data/lib/active_support/core_ext/numeric/time.rb +74 -0
  100. data/lib/active_support/core_ext/object.rb +14 -0
  101. data/lib/active_support/core_ext/object/acts_like.rb +10 -0
  102. data/lib/active_support/core_ext/object/blank.rb +143 -0
  103. data/lib/active_support/core_ext/object/conversions.rb +4 -0
  104. data/lib/active_support/core_ext/object/deep_dup.rb +53 -0
  105. data/lib/active_support/core_ext/object/duplicable.rb +124 -0
  106. data/lib/active_support/core_ext/object/inclusion.rb +27 -0
  107. data/lib/active_support/core_ext/object/instance_variables.rb +28 -0
  108. data/lib/active_support/core_ext/object/json.rb +205 -0
  109. data/lib/active_support/core_ext/object/to_param.rb +1 -0
  110. data/lib/active_support/core_ext/object/to_query.rb +84 -0
  111. data/lib/active_support/core_ext/object/try.rb +146 -0
  112. data/lib/active_support/core_ext/object/with_options.rb +69 -0
  113. data/lib/active_support/core_ext/range.rb +4 -0
  114. data/lib/active_support/core_ext/range/conversions.rb +31 -0
  115. data/lib/active_support/core_ext/range/each.rb +21 -0
  116. data/lib/active_support/core_ext/range/include_range.rb +23 -0
  117. data/lib/active_support/core_ext/range/overlaps.rb +8 -0
  118. data/lib/active_support/core_ext/regexp.rb +5 -0
  119. data/lib/active_support/core_ext/securerandom.rb +23 -0
  120. data/lib/active_support/core_ext/string.rb +13 -0
  121. data/lib/active_support/core_ext/string/access.rb +104 -0
  122. data/lib/active_support/core_ext/string/behavior.rb +6 -0
  123. data/lib/active_support/core_ext/string/conversions.rb +57 -0
  124. data/lib/active_support/core_ext/string/exclude.rb +11 -0
  125. data/lib/active_support/core_ext/string/filters.rb +102 -0
  126. data/lib/active_support/core_ext/string/indent.rb +43 -0
  127. data/lib/active_support/core_ext/string/inflections.rb +244 -0
  128. data/lib/active_support/core_ext/string/inquiry.rb +13 -0
  129. data/lib/active_support/core_ext/string/multibyte.rb +53 -0
  130. data/lib/active_support/core_ext/string/output_safety.rb +260 -0
  131. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -0
  132. data/lib/active_support/core_ext/string/strip.rb +23 -0
  133. data/lib/active_support/core_ext/string/zones.rb +14 -0
  134. data/lib/active_support/core_ext/struct.rb +3 -0
  135. data/lib/active_support/core_ext/time.rb +5 -0
  136. data/lib/active_support/core_ext/time/acts_like.rb +8 -0
  137. data/lib/active_support/core_ext/time/calculations.rb +290 -0
  138. data/lib/active_support/core_ext/time/compatibility.rb +14 -0
  139. data/lib/active_support/core_ext/time/conversions.rb +67 -0
  140. data/lib/active_support/core_ext/time/marshal.rb +3 -0
  141. data/lib/active_support/core_ext/time/zones.rb +111 -0
  142. data/lib/active_support/core_ext/uri.rb +24 -0
  143. data/lib/active_support/dependencies.rb +755 -0
  144. data/lib/active_support/dependencies/autoload.rb +77 -0
  145. data/lib/active_support/dependencies/interlock.rb +55 -0
  146. data/lib/active_support/deprecation.rb +43 -0
  147. data/lib/active_support/deprecation/behaviors.rb +90 -0
  148. data/lib/active_support/deprecation/instance_delegator.rb +37 -0
  149. data/lib/active_support/deprecation/method_wrappers.rb +70 -0
  150. data/lib/active_support/deprecation/proxy_wrappers.rb +149 -0
  151. data/lib/active_support/deprecation/reporting.rb +112 -0
  152. data/lib/active_support/descendants_tracker.rb +60 -0
  153. data/lib/active_support/duration.rb +235 -0
  154. data/lib/active_support/duration/iso8601_parser.rb +122 -0
  155. data/lib/active_support/duration/iso8601_serializer.rb +51 -0
  156. data/lib/active_support/evented_file_update_checker.rb +199 -0
  157. data/lib/active_support/execution_wrapper.rb +126 -0
  158. data/lib/active_support/executor.rb +6 -0
  159. data/lib/active_support/file_update_checker.rb +157 -0
  160. data/lib/active_support/gem_version.rb +15 -0
  161. data/lib/active_support/gzip.rb +36 -0
  162. data/lib/active_support/hash_with_indifferent_access.rb +329 -0
  163. data/lib/active_support/i18n.rb +13 -0
  164. data/lib/active_support/i18n_railtie.rb +115 -0
  165. data/lib/active_support/inflections.rb +70 -0
  166. data/lib/active_support/inflector.rb +7 -0
  167. data/lib/active_support/inflector/inflections.rb +242 -0
  168. data/lib/active_support/inflector/methods.rb +390 -0
  169. data/lib/active_support/inflector/transliterate.rb +112 -0
  170. data/lib/active_support/json.rb +2 -0
  171. data/lib/active_support/json/decoding.rb +74 -0
  172. data/lib/active_support/json/encoding.rb +127 -0
  173. data/lib/active_support/key_generator.rb +71 -0
  174. data/lib/active_support/lazy_load_hooks.rb +76 -0
  175. data/lib/active_support/locale/en.yml +135 -0
  176. data/lib/active_support/log_subscriber.rb +109 -0
  177. data/lib/active_support/log_subscriber/test_helper.rb +104 -0
  178. data/lib/active_support/logger.rb +106 -0
  179. data/lib/active_support/logger_silence.rb +28 -0
  180. data/lib/active_support/logger_thread_safe_level.rb +31 -0
  181. data/lib/active_support/message_encryptor.rb +114 -0
  182. data/lib/active_support/message_verifier.rb +134 -0
  183. data/lib/active_support/multibyte.rb +21 -0
  184. data/lib/active_support/multibyte/chars.rb +231 -0
  185. data/lib/active_support/multibyte/unicode.rb +413 -0
  186. data/lib/active_support/notifications.rb +212 -0
  187. data/lib/active_support/notifications/fanout.rb +157 -0
  188. data/lib/active_support/notifications/instrumenter.rb +91 -0
  189. data/lib/active_support/number_helper.rb +368 -0
  190. data/lib/active_support/number_helper/number_converter.rb +182 -0
  191. data/lib/active_support/number_helper/number_to_currency_converter.rb +44 -0
  192. data/lib/active_support/number_helper/number_to_delimited_converter.rb +28 -0
  193. data/lib/active_support/number_helper/number_to_human_converter.rb +68 -0
  194. data/lib/active_support/number_helper/number_to_human_size_converter.rb +62 -0
  195. data/lib/active_support/number_helper/number_to_percentage_converter.rb +12 -0
  196. data/lib/active_support/number_helper/number_to_phone_converter.rb +58 -0
  197. data/lib/active_support/number_helper/number_to_rounded_converter.rb +92 -0
  198. data/lib/active_support/option_merger.rb +25 -0
  199. data/lib/active_support/ordered_hash.rb +48 -0
  200. data/lib/active_support/ordered_options.rb +81 -0
  201. data/lib/active_support/per_thread_registry.rb +58 -0
  202. data/lib/active_support/proxy_object.rb +13 -0
  203. data/lib/active_support/rails.rb +27 -0
  204. data/lib/active_support/railtie.rb +51 -0
  205. data/lib/active_support/reloader.rb +129 -0
  206. data/lib/active_support/rescuable.rb +173 -0
  207. data/lib/active_support/security_utils.rb +27 -0
  208. data/lib/active_support/string_inquirer.rb +26 -0
  209. data/lib/active_support/subscriber.rb +120 -0
  210. data/lib/active_support/tagged_logging.rb +77 -0
  211. data/lib/active_support/test_case.rb +88 -0
  212. data/lib/active_support/testing/assertions.rb +99 -0
  213. data/lib/active_support/testing/autorun.rb +5 -0
  214. data/lib/active_support/testing/constant_lookup.rb +50 -0
  215. data/lib/active_support/testing/declarative.rb +26 -0
  216. data/lib/active_support/testing/deprecation.rb +36 -0
  217. data/lib/active_support/testing/file_fixtures.rb +34 -0
  218. data/lib/active_support/testing/isolation.rb +115 -0
  219. data/lib/active_support/testing/method_call_assertions.rb +41 -0
  220. data/lib/active_support/testing/setup_and_teardown.rb +50 -0
  221. data/lib/active_support/testing/stream.rb +42 -0
  222. data/lib/active_support/testing/tagged_logging.rb +25 -0
  223. data/lib/active_support/testing/time_helpers.rb +136 -0
  224. data/lib/active_support/time.rb +18 -0
  225. data/lib/active_support/time_with_zone.rb +511 -0
  226. data/lib/active_support/values/time_zone.rb +484 -0
  227. data/lib/active_support/values/unicode_tables.dat +0 -0
  228. data/lib/active_support/version.rb +8 -0
  229. data/lib/active_support/xml_mini.rb +209 -0
  230. data/lib/active_support/xml_mini/jdom.rb +181 -0
  231. data/lib/active_support/xml_mini/libxml.rb +77 -0
  232. data/lib/active_support/xml_mini/libxmlsax.rb +82 -0
  233. data/lib/active_support/xml_mini/nokogiri.rb +81 -0
  234. data/lib/active_support/xml_mini/nokogirisax.rb +85 -0
  235. data/lib/active_support/xml_mini/rexml.rb +128 -0
  236. metadata +350 -0
@@ -0,0 +1,15 @@
1
+ module ActiveSupport
2
+ # Returns the version of the currently loaded Active Support as a <tt>Gem::Version</tt>.
3
+ def self.gem_version
4
+ Gem::Version.new VERSION::STRING
5
+ end
6
+
7
+ module VERSION
8
+ MAJOR = 5
9
+ MINOR = 0
10
+ TINY = 7
11
+ PRE = "1"
12
+
13
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
14
+ end
15
+ end
@@ -0,0 +1,36 @@
1
+ require 'zlib'
2
+ require 'stringio'
3
+
4
+ module ActiveSupport
5
+ # A convenient wrapper for the zlib standard library that allows
6
+ # compression/decompression of strings with gzip.
7
+ #
8
+ # gzip = ActiveSupport::Gzip.compress('compress me!')
9
+ # # => "\x1F\x8B\b\x00o\x8D\xCDO\x00\x03K\xCE\xCF-(J-.V\xC8MU\x04\x00R>n\x83\f\x00\x00\x00"
10
+ #
11
+ # ActiveSupport::Gzip.decompress(gzip)
12
+ # # => "compress me!"
13
+ module Gzip
14
+ class Stream < StringIO
15
+ def initialize(*)
16
+ super
17
+ set_encoding "BINARY"
18
+ end
19
+ def close; rewind; end
20
+ end
21
+
22
+ # Decompresses a gzipped string.
23
+ def self.decompress(source)
24
+ Zlib::GzipReader.wrap(StringIO.new(source), &:read)
25
+ end
26
+
27
+ # Compresses a string using gzip.
28
+ def self.compress(source, level=Zlib::DEFAULT_COMPRESSION, strategy=Zlib::DEFAULT_STRATEGY)
29
+ output = Stream.new
30
+ gz = Zlib::GzipWriter.new(output, level, strategy)
31
+ gz.write(source)
32
+ gz.close
33
+ output.string
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,329 @@
1
+ require 'active_support/core_ext/hash/keys'
2
+ require 'active_support/core_ext/hash/reverse_merge'
3
+
4
+ module ActiveSupport
5
+ # Implements a hash where keys <tt>:foo</tt> and <tt>"foo"</tt> are considered
6
+ # to be the same.
7
+ #
8
+ # rgb = ActiveSupport::HashWithIndifferentAccess.new
9
+ #
10
+ # rgb[:black] = '#000000'
11
+ # rgb[:black] # => '#000000'
12
+ # rgb['black'] # => '#000000'
13
+ #
14
+ # rgb['white'] = '#FFFFFF'
15
+ # rgb[:white] # => '#FFFFFF'
16
+ # rgb['white'] # => '#FFFFFF'
17
+ #
18
+ # Internally symbols are mapped to strings when used as keys in the entire
19
+ # writing interface (calling <tt>[]=</tt>, <tt>merge</tt>, etc). This
20
+ # mapping belongs to the public interface. For example, given:
21
+ #
22
+ # hash = ActiveSupport::HashWithIndifferentAccess.new(a: 1)
23
+ #
24
+ # You are guaranteed that the key is returned as a string:
25
+ #
26
+ # hash.keys # => ["a"]
27
+ #
28
+ # Technically other types of keys are accepted:
29
+ #
30
+ # hash = ActiveSupport::HashWithIndifferentAccess.new(a: 1)
31
+ # hash[0] = 0
32
+ # hash # => {"a"=>1, 0=>0}
33
+ #
34
+ # but this class is intended for use cases where strings or symbols are the
35
+ # expected keys and it is convenient to understand both as the same. For
36
+ # example the +params+ hash in Ruby on Rails.
37
+ #
38
+ # Note that core extensions define <tt>Hash#with_indifferent_access</tt>:
39
+ #
40
+ # rgb = { black: '#000000', white: '#FFFFFF' }.with_indifferent_access
41
+ #
42
+ # which may be handy.
43
+ #
44
+ # To access this class outside of Rails, require the core extension with:
45
+ #
46
+ # require "active_support/core_ext/hash/indifferent_access"
47
+ #
48
+ # which will, in turn, require this file.
49
+ class HashWithIndifferentAccess < Hash
50
+ # Returns +true+ so that <tt>Array#extract_options!</tt> finds members of
51
+ # this class.
52
+ def extractable_options?
53
+ true
54
+ end
55
+
56
+ def with_indifferent_access
57
+ dup
58
+ end
59
+
60
+ def nested_under_indifferent_access
61
+ self
62
+ end
63
+
64
+ def initialize(constructor = {})
65
+ if constructor.respond_to?(:to_hash)
66
+ super()
67
+ update(constructor)
68
+
69
+ hash = constructor.to_hash
70
+ self.default = hash.default if hash.default
71
+ self.default_proc = hash.default_proc if hash.default_proc
72
+ else
73
+ super(constructor)
74
+ end
75
+ end
76
+
77
+ def default(*args)
78
+ arg_key = args.first
79
+
80
+ if include?(key = convert_key(arg_key))
81
+ self[key]
82
+ else
83
+ super
84
+ end
85
+ end
86
+
87
+ def self.new_from_hash_copying_default(hash)
88
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
89
+ `ActiveSupport::HashWithIndifferentAccess.new_from_hash_copying_default`
90
+ has been deprecated, and will be removed in Rails 5.1. The behavior of
91
+ this method is now identical to the behavior of `.new`.
92
+ MSG
93
+ new(hash)
94
+ end
95
+
96
+ def self.[](*args)
97
+ new.merge!(Hash[*args])
98
+ end
99
+
100
+ alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
101
+ alias_method :regular_update, :update unless method_defined?(:regular_update)
102
+
103
+ # Assigns a new value to the hash:
104
+ #
105
+ # hash = ActiveSupport::HashWithIndifferentAccess.new
106
+ # hash[:key] = 'value'
107
+ #
108
+ # This value can be later fetched using either +:key+ or <tt>'key'</tt>.
109
+ def []=(key, value)
110
+ regular_writer(convert_key(key), convert_value(value, for: :assignment))
111
+ end
112
+
113
+ alias_method :store, :[]=
114
+
115
+ # Updates the receiver in-place, merging in the hash passed as argument:
116
+ #
117
+ # hash_1 = ActiveSupport::HashWithIndifferentAccess.new
118
+ # hash_1[:key] = 'value'
119
+ #
120
+ # hash_2 = ActiveSupport::HashWithIndifferentAccess.new
121
+ # hash_2[:key] = 'New Value!'
122
+ #
123
+ # hash_1.update(hash_2) # => {"key"=>"New Value!"}
124
+ #
125
+ # The argument can be either an
126
+ # <tt>ActiveSupport::HashWithIndifferentAccess</tt> or a regular +Hash+.
127
+ # In either case the merge respects the semantics of indifferent access.
128
+ #
129
+ # If the argument is a regular hash with keys +:key+ and +"key"+ only one
130
+ # of the values end up in the receiver, but which one is unspecified.
131
+ #
132
+ # When given a block, the value for duplicated keys will be determined
133
+ # by the result of invoking the block with the duplicated key, the value
134
+ # in the receiver, and the value in +other_hash+. The rules for duplicated
135
+ # keys follow the semantics of indifferent access:
136
+ #
137
+ # hash_1[:key] = 10
138
+ # hash_2['key'] = 12
139
+ # hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22}
140
+ def update(other_hash)
141
+ if other_hash.is_a? HashWithIndifferentAccess
142
+ super(other_hash)
143
+ else
144
+ other_hash.to_hash.each_pair do |key, value|
145
+ if block_given? && key?(key)
146
+ value = yield(convert_key(key), self[key], value)
147
+ end
148
+ regular_writer(convert_key(key), convert_value(value))
149
+ end
150
+ self
151
+ end
152
+ end
153
+
154
+ alias_method :merge!, :update
155
+
156
+ # Checks the hash for a key matching the argument passed in:
157
+ #
158
+ # hash = ActiveSupport::HashWithIndifferentAccess.new
159
+ # hash['key'] = 'value'
160
+ # hash.key?(:key) # => true
161
+ # hash.key?('key') # => true
162
+ def key?(key)
163
+ super(convert_key(key))
164
+ end
165
+
166
+ alias_method :include?, :key?
167
+ alias_method :has_key?, :key?
168
+ alias_method :member?, :key?
169
+
170
+
171
+ # Same as <tt>Hash#[]</tt> where the key passed as argument can be
172
+ # either a string or a symbol:
173
+ #
174
+ # counters = ActiveSupport::HashWithIndifferentAccess.new
175
+ # counters[:foo] = 1
176
+ #
177
+ # counters['foo'] # => 1
178
+ # counters[:foo] # => 1
179
+ # counters[:zoo] # => nil
180
+ def [](key)
181
+ super(convert_key(key))
182
+ end
183
+
184
+ # Same as <tt>Hash#fetch</tt> where the key passed as argument can be
185
+ # either a string or a symbol:
186
+ #
187
+ # counters = ActiveSupport::HashWithIndifferentAccess.new
188
+ # counters[:foo] = 1
189
+ #
190
+ # counters.fetch('foo') # => 1
191
+ # counters.fetch(:bar, 0) # => 0
192
+ # counters.fetch(:bar) { |key| 0 } # => 0
193
+ # counters.fetch(:zoo) # => KeyError: key not found: "zoo"
194
+ def fetch(key, *extras)
195
+ super(convert_key(key), *extras)
196
+ end
197
+
198
+ # Returns an array of the values at the specified indices:
199
+ #
200
+ # hash = ActiveSupport::HashWithIndifferentAccess.new
201
+ # hash[:a] = 'x'
202
+ # hash[:b] = 'y'
203
+ # hash.values_at('a', 'b') # => ["x", "y"]
204
+ def values_at(*indices)
205
+ indices.collect { |key| self[convert_key(key)] }
206
+ end
207
+
208
+ # Returns a shallow copy of the hash.
209
+ #
210
+ # hash = ActiveSupport::HashWithIndifferentAccess.new({ a: { b: 'b' } })
211
+ # dup = hash.dup
212
+ # dup[:a][:c] = 'c'
213
+ #
214
+ # hash[:a][:c] # => "c"
215
+ # dup[:a][:c] # => "c"
216
+ def dup
217
+ self.class.new(self).tap do |new_hash|
218
+ set_defaults(new_hash)
219
+ end
220
+ end
221
+
222
+ # This method has the same semantics of +update+, except it does not
223
+ # modify the receiver but rather returns a new hash with indifferent
224
+ # access with the result of the merge.
225
+ def merge(hash, &block)
226
+ self.dup.update(hash, &block)
227
+ end
228
+
229
+ # Like +merge+ but the other way around: Merges the receiver into the
230
+ # argument and returns a new hash with indifferent access as result:
231
+ #
232
+ # hash = ActiveSupport::HashWithIndifferentAccess.new
233
+ # hash['a'] = nil
234
+ # hash.reverse_merge(a: 0, b: 1) # => {"a"=>nil, "b"=>1}
235
+ def reverse_merge(other_hash)
236
+ super(self.class.new(other_hash))
237
+ end
238
+
239
+ # Same semantics as +reverse_merge+ but modifies the receiver in-place.
240
+ def reverse_merge!(other_hash)
241
+ replace(reverse_merge( other_hash ))
242
+ end
243
+
244
+ # Replaces the contents of this hash with other_hash.
245
+ #
246
+ # h = { "a" => 100, "b" => 200 }
247
+ # h.replace({ "c" => 300, "d" => 400 }) # => {"c"=>300, "d"=>400}
248
+ def replace(other_hash)
249
+ super(self.class.new(other_hash))
250
+ end
251
+
252
+ # Removes the specified key from the hash.
253
+ def delete(key)
254
+ super(convert_key(key))
255
+ end
256
+
257
+ def stringify_keys!; self end
258
+ def deep_stringify_keys!; self end
259
+ def stringify_keys; dup end
260
+ def deep_stringify_keys; dup end
261
+ undef :symbolize_keys!
262
+ undef :deep_symbolize_keys!
263
+ def symbolize_keys; to_hash.symbolize_keys! end
264
+ def deep_symbolize_keys; to_hash.deep_symbolize_keys! end
265
+ def to_options!; self end
266
+
267
+ def select(*args, &block)
268
+ return to_enum(:select) unless block_given?
269
+ dup.tap { |hash| hash.select!(*args, &block) }
270
+ end
271
+
272
+ def reject(*args, &block)
273
+ return to_enum(:reject) unless block_given?
274
+ dup.tap { |hash| hash.reject!(*args, &block) }
275
+ end
276
+
277
+ def transform_values(*args, &block)
278
+ return to_enum(:transform_values) unless block_given?
279
+ dup.tap { |hash| hash.transform_values!(*args, &block) }
280
+ end
281
+
282
+ def compact
283
+ dup.tap(&:compact!)
284
+ end
285
+
286
+ # Convert to a regular hash with string keys.
287
+ def to_hash
288
+ _new_hash = Hash.new
289
+ set_defaults(_new_hash)
290
+
291
+ each do |key, value|
292
+ _new_hash[key] = convert_value(value, for: :to_hash)
293
+ end
294
+ _new_hash
295
+ end
296
+
297
+ protected
298
+ def convert_key(key)
299
+ key.kind_of?(Symbol) ? key.to_s : key
300
+ end
301
+
302
+ def convert_value(value, options = {})
303
+ if value.is_a? Hash
304
+ if options[:for] == :to_hash
305
+ value.to_hash
306
+ else
307
+ value.nested_under_indifferent_access
308
+ end
309
+ elsif value.is_a?(Array)
310
+ if options[:for] != :assignment || value.frozen?
311
+ value = value.dup
312
+ end
313
+ value.map! { |e| convert_value(e, options) }
314
+ else
315
+ value
316
+ end
317
+ end
318
+
319
+ def set_defaults(target)
320
+ if default_proc
321
+ target.default_proc = default_proc.dup
322
+ else
323
+ target.default = default
324
+ end
325
+ end
326
+ end
327
+ end
328
+
329
+ HashWithIndifferentAccess = ActiveSupport::HashWithIndifferentAccess
@@ -0,0 +1,13 @@
1
+ require 'active_support/core_ext/hash/deep_merge'
2
+ require 'active_support/core_ext/hash/except'
3
+ require 'active_support/core_ext/hash/slice'
4
+ begin
5
+ require 'i18n'
6
+ rescue LoadError => e
7
+ $stderr.puts "The i18n gem is not available. Please add it to your Gemfile and run bundle install"
8
+ raise e
9
+ end
10
+ require 'active_support/lazy_load_hooks'
11
+
12
+ ActiveSupport.run_load_hooks(:i18n)
13
+ I18n.load_path << "#{File.dirname(__FILE__)}/locale/en.yml"
@@ -0,0 +1,115 @@
1
+ require "active_support"
2
+ require "active_support/file_update_checker"
3
+ require "active_support/core_ext/array/wrap"
4
+
5
+ module I18n
6
+ class Railtie < Rails::Railtie
7
+ config.i18n = ActiveSupport::OrderedOptions.new
8
+ config.i18n.railties_load_path = []
9
+ config.i18n.load_path = []
10
+ config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
11
+
12
+ # Set the i18n configuration after initialization since a lot of
13
+ # configuration is still usually done in application initializers.
14
+ config.after_initialize do |app|
15
+ I18n::Railtie.initialize_i18n(app)
16
+ end
17
+
18
+ # Trigger i18n config before any eager loading has happened
19
+ # so it's ready if any classes require it when eager loaded.
20
+ config.before_eager_load do |app|
21
+ I18n::Railtie.initialize_i18n(app)
22
+ end
23
+
24
+ protected
25
+
26
+ @i18n_inited = false
27
+
28
+ # Setup i18n configuration.
29
+ def self.initialize_i18n(app)
30
+ return if @i18n_inited
31
+
32
+ fallbacks = app.config.i18n.delete(:fallbacks)
33
+
34
+ # Avoid issues with setting the default_locale by disabling available locales
35
+ # check while configuring.
36
+ enforce_available_locales = app.config.i18n.delete(:enforce_available_locales)
37
+ enforce_available_locales = I18n.enforce_available_locales if enforce_available_locales.nil?
38
+ I18n.enforce_available_locales = false
39
+
40
+ reloadable_paths = []
41
+ app.config.i18n.each do |setting, value|
42
+ case setting
43
+ when :railties_load_path
44
+ reloadable_paths = value
45
+ app.config.i18n.load_path.unshift(*value.map(&:existent).flatten)
46
+ when :load_path
47
+ I18n.load_path += value
48
+ else
49
+ I18n.send("#{setting}=", value)
50
+ end
51
+ end
52
+
53
+ init_fallbacks(fallbacks) if fallbacks && validate_fallbacks(fallbacks)
54
+
55
+ # Restore available locales check so it will take place from now on.
56
+ I18n.enforce_available_locales = enforce_available_locales
57
+
58
+ directories = watched_dirs_with_extensions(reloadable_paths)
59
+ reloader = app.config.file_watcher.new(I18n.load_path.dup, directories) do
60
+ I18n.load_path.keep_if { |p| File.exist?(p) }
61
+ I18n.load_path |= reloadable_paths.map(&:existent).flatten
62
+
63
+ I18n.reload!
64
+ end
65
+
66
+ app.reloaders << reloader
67
+ app.reloader.to_run do
68
+ reloader.execute_if_updated { require_unload_lock! }
69
+ # TODO: remove the following line as soon as the return value of
70
+ # callbacks is ignored, that is, returning `false` does not
71
+ # display a deprecation warning or halts the callback chain.
72
+ true
73
+ end
74
+ reloader.execute
75
+
76
+ @i18n_inited = true
77
+ end
78
+
79
+ def self.include_fallbacks_module
80
+ I18n.backend.class.include(I18n::Backend::Fallbacks)
81
+ end
82
+
83
+ def self.init_fallbacks(fallbacks)
84
+ include_fallbacks_module
85
+
86
+ args = case fallbacks
87
+ when ActiveSupport::OrderedOptions
88
+ [*(fallbacks[:defaults] || []) << fallbacks[:map]].compact
89
+ when Hash, Array
90
+ Array.wrap(fallbacks)
91
+ else # TrueClass
92
+ []
93
+ end
94
+
95
+ I18n.fallbacks = I18n::Locale::Fallbacks.new(*args)
96
+ end
97
+
98
+ def self.validate_fallbacks(fallbacks)
99
+ case fallbacks
100
+ when ActiveSupport::OrderedOptions
101
+ !fallbacks.empty?
102
+ when TrueClass, Array, Hash
103
+ true
104
+ else
105
+ raise "Unexpected fallback type #{fallbacks.inspect}"
106
+ end
107
+ end
108
+
109
+ def self.watched_dirs_with_extensions(paths)
110
+ paths.each_with_object({}) do |path, result|
111
+ result[path.absolute_current] = path.extensions
112
+ end
113
+ end
114
+ end
115
+ end