activesupport 3.2.22.5 → 4.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (214) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +325 -136
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -2
  5. data/lib/active_support.rb +8 -21
  6. data/lib/active_support/backtrace_cleaner.rb +33 -25
  7. data/lib/active_support/basic_object.rb +7 -17
  8. data/lib/active_support/benchmarkable.rb +19 -15
  9. data/lib/active_support/buffered_logger.rb +9 -113
  10. data/lib/active_support/cache.rb +203 -171
  11. data/lib/active_support/cache/file_store.rb +12 -12
  12. data/lib/active_support/cache/mem_cache_store.rb +24 -30
  13. data/lib/active_support/cache/memory_store.rb +2 -0
  14. data/lib/active_support/callbacks.rb +195 -247
  15. data/lib/active_support/concern.rb +16 -23
  16. data/lib/active_support/concurrency/latch.rb +27 -0
  17. data/lib/active_support/configurable.rb +69 -12
  18. data/lib/active_support/core_ext.rb +1 -0
  19. data/lib/active_support/core_ext/array.rb +0 -1
  20. data/lib/active_support/core_ext/array/access.rb +17 -9
  21. data/lib/active_support/core_ext/array/conversions.rb +113 -55
  22. data/lib/active_support/core_ext/array/extract_options.rb +2 -2
  23. data/lib/active_support/core_ext/array/grouping.rb +21 -22
  24. data/lib/active_support/core_ext/array/uniq_by.rb +12 -9
  25. data/lib/active_support/core_ext/array/wrap.rb +11 -14
  26. data/lib/active_support/core_ext/big_decimal/conversions.rb +7 -24
  27. data/lib/active_support/core_ext/class/attribute.rb +12 -8
  28. data/lib/active_support/core_ext/class/attribute_accessors.rb +14 -12
  29. data/lib/active_support/core_ext/class/delegating_attributes.rb +15 -19
  30. data/lib/active_support/core_ext/class/subclasses.rb +11 -5
  31. data/lib/active_support/core_ext/date.rb +6 -0
  32. data/lib/active_support/core_ext/date/calculations.rb +34 -188
  33. data/lib/active_support/core_ext/date/conversions.rb +16 -38
  34. data/lib/active_support/core_ext/date/infinite_comparable.rb +5 -0
  35. data/lib/active_support/core_ext/date/zones.rb +25 -2
  36. data/lib/active_support/core_ext/date_and_time/calculations.rb +232 -0
  37. data/lib/active_support/core_ext/date_time.rb +5 -0
  38. data/lib/active_support/core_ext/date_time/acts_like.rb +0 -1
  39. data/lib/active_support/core_ext/date_time/calculations.rb +73 -65
  40. data/lib/active_support/core_ext/date_time/conversions.rb +21 -33
  41. data/lib/active_support/core_ext/date_time/infinite_comparable.rb +5 -0
  42. data/lib/active_support/core_ext/date_time/zones.rb +11 -8
  43. data/lib/active_support/core_ext/enumerable.rb +26 -73
  44. data/lib/active_support/core_ext/file.rb +0 -1
  45. data/lib/active_support/core_ext/file/atomic.rb +27 -11
  46. data/lib/active_support/core_ext/hash.rb +0 -1
  47. data/lib/active_support/core_ext/hash/conversions.rb +145 -79
  48. data/lib/active_support/core_ext/hash/deep_merge.rb +14 -8
  49. data/lib/active_support/core_ext/hash/diff.rb +5 -4
  50. data/lib/active_support/core_ext/hash/except.rb +1 -9
  51. data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -5
  52. data/lib/active_support/core_ext/hash/keys.rb +108 -24
  53. data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -3
  54. data/lib/active_support/core_ext/hash/slice.rb +12 -12
  55. data/lib/active_support/core_ext/infinite_comparable.rb +35 -0
  56. data/lib/active_support/core_ext/integer/inflections.rb +13 -1
  57. data/lib/active_support/core_ext/integer/time.rb +17 -12
  58. data/lib/active_support/core_ext/kernel/debugger.rb +2 -2
  59. data/lib/active_support/core_ext/kernel/reporting.rb +36 -22
  60. data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -7
  61. data/lib/active_support/core_ext/load_error.rb +7 -5
  62. data/lib/active_support/core_ext/logger.rb +7 -23
  63. data/lib/active_support/core_ext/marshal.rb +19 -0
  64. data/lib/active_support/core_ext/module.rb +1 -3
  65. data/lib/active_support/core_ext/module/aliasing.rb +8 -9
  66. data/lib/active_support/core_ext/module/anonymous.rb +2 -7
  67. data/lib/active_support/core_ext/module/attr_internal.rb +0 -1
  68. data/lib/active_support/core_ext/module/attribute_accessors.rb +12 -10
  69. data/lib/active_support/core_ext/module/delegation.rb +57 -40
  70. data/lib/active_support/core_ext/module/deprecation.rb +19 -3
  71. data/lib/active_support/core_ext/module/introspection.rb +17 -27
  72. data/lib/active_support/core_ext/module/qualified_const.rb +8 -20
  73. data/lib/active_support/core_ext/module/remove_method.rb +1 -5
  74. data/lib/active_support/core_ext/numeric.rb +2 -0
  75. data/lib/active_support/core_ext/numeric/conversions.rb +135 -0
  76. data/lib/active_support/core_ext/numeric/infinite_comparable.rb +9 -0
  77. data/lib/active_support/core_ext/numeric/time.rb +6 -6
  78. data/lib/active_support/core_ext/object.rb +1 -0
  79. data/lib/active_support/core_ext/object/acts_like.rb +4 -4
  80. data/lib/active_support/core_ext/object/blank.rb +7 -23
  81. data/lib/active_support/core_ext/object/deep_dup.rb +46 -0
  82. data/lib/active_support/core_ext/object/duplicable.rb +1 -30
  83. data/lib/active_support/core_ext/object/inclusion.rb +6 -6
  84. data/lib/active_support/core_ext/object/instance_variables.rb +7 -12
  85. data/lib/active_support/core_ext/object/to_json.rb +8 -0
  86. data/lib/active_support/core_ext/object/to_param.rb +5 -2
  87. data/lib/active_support/core_ext/object/try.rb +46 -25
  88. data/lib/active_support/core_ext/object/with_options.rb +7 -8
  89. data/lib/active_support/core_ext/proc.rb +3 -0
  90. data/lib/active_support/core_ext/range.rb +0 -2
  91. data/lib/active_support/core_ext/range/conversions.rb +0 -2
  92. data/lib/active_support/core_ext/range/include_range.rb +1 -1
  93. data/lib/active_support/core_ext/range/overlaps.rb +1 -1
  94. data/lib/active_support/core_ext/string.rb +2 -2
  95. data/lib/active_support/core_ext/string/access.rb +95 -90
  96. data/lib/active_support/core_ext/string/conversions.rb +29 -38
  97. data/lib/active_support/core_ext/string/encoding.rb +6 -9
  98. data/lib/active_support/core_ext/string/filters.rb +24 -18
  99. data/lib/active_support/core_ext/string/indent.rb +43 -0
  100. data/lib/active_support/core_ext/string/inflections.rb +70 -60
  101. data/lib/active_support/core_ext/string/inquiry.rb +2 -2
  102. data/lib/active_support/core_ext/string/multibyte.rb +41 -64
  103. data/lib/active_support/core_ext/string/output_safety.rb +59 -51
  104. data/lib/active_support/core_ext/string/zones.rb +13 -0
  105. data/lib/active_support/core_ext/struct.rb +6 -0
  106. data/lib/active_support/core_ext/thread.rb +74 -0
  107. data/lib/active_support/core_ext/time.rb +6 -0
  108. data/lib/active_support/core_ext/time/calculations.rb +105 -193
  109. data/lib/active_support/core_ext/time/conversions.rb +27 -51
  110. data/lib/active_support/core_ext/time/infinite_comparable.rb +5 -0
  111. data/lib/active_support/core_ext/time/marshal.rb +0 -27
  112. data/lib/active_support/core_ext/time/zones.rb +27 -17
  113. data/lib/active_support/core_ext/uri.rb +13 -17
  114. data/lib/active_support/dependencies.rb +160 -141
  115. data/lib/active_support/dependencies/autoload.rb +47 -20
  116. data/lib/active_support/deprecation.rb +39 -14
  117. data/lib/active_support/deprecation/behaviors.rb +44 -30
  118. data/lib/active_support/deprecation/instance_delegator.rb +24 -0
  119. data/lib/active_support/deprecation/method_wrappers.rb +33 -18
  120. data/lib/active_support/deprecation/proxy_wrappers.rb +58 -13
  121. data/lib/active_support/deprecation/reporting.rb +40 -11
  122. data/lib/active_support/descendants_tracker.rb +34 -19
  123. data/lib/active_support/duration.rb +6 -8
  124. data/lib/active_support/file_update_checker.rb +63 -47
  125. data/lib/active_support/gzip.rb +11 -5
  126. data/lib/active_support/hash_with_indifferent_access.rb +112 -37
  127. data/lib/active_support/i18n.rb +4 -0
  128. data/lib/active_support/i18n_railtie.rb +5 -22
  129. data/lib/active_support/inflections.rb +14 -12
  130. data/lib/active_support/inflector/inflections.rb +108 -71
  131. data/lib/active_support/inflector/methods.rb +181 -160
  132. data/lib/active_support/inflector/transliterate.rb +16 -17
  133. data/lib/active_support/json/decoding.rb +18 -17
  134. data/lib/active_support/json/encoding.rb +93 -39
  135. data/lib/active_support/json/variable.rb +10 -1
  136. data/lib/active_support/key_generator.rb +75 -0
  137. data/lib/active_support/lazy_load_hooks.rb +21 -19
  138. data/lib/active_support/locale/en.yml +100 -3
  139. data/lib/active_support/log_subscriber.rb +56 -36
  140. data/lib/active_support/log_subscriber/test_helper.rb +18 -15
  141. data/lib/active_support/logger.rb +57 -0
  142. data/lib/active_support/logger_silence.rb +24 -0
  143. data/lib/active_support/message_encryptor.rb +32 -29
  144. data/lib/active_support/message_verifier.rb +8 -14
  145. data/lib/active_support/multibyte.rb +5 -28
  146. data/lib/active_support/multibyte/chars.rb +80 -333
  147. data/lib/active_support/multibyte/unicode.rb +74 -64
  148. data/lib/active_support/notifications.rb +57 -25
  149. data/lib/active_support/notifications/fanout.rb +105 -18
  150. data/lib/active_support/notifications/instrumenter.rb +32 -13
  151. data/lib/active_support/number_helper.rb +636 -0
  152. data/lib/active_support/ordered_hash.rb +8 -190
  153. data/lib/active_support/ordered_options.rb +21 -23
  154. data/lib/active_support/proxy_object.rb +13 -0
  155. data/lib/active_support/rails.rb +27 -0
  156. data/lib/active_support/railtie.rb +12 -32
  157. data/lib/active_support/rescuable.rb +9 -4
  158. data/lib/active_support/string_inquirer.rb +13 -8
  159. data/lib/active_support/tagged_logging.rb +51 -73
  160. data/lib/active_support/test_case.rb +46 -17
  161. data/lib/active_support/testing/assertions.rb +56 -26
  162. data/lib/active_support/testing/autorun.rb +5 -0
  163. data/lib/active_support/testing/constant_lookup.rb +52 -0
  164. data/lib/active_support/testing/declarative.rb +1 -1
  165. data/lib/active_support/testing/deprecation.rb +0 -19
  166. data/lib/active_support/testing/isolation.rb +25 -58
  167. data/lib/active_support/testing/pending.rb +5 -43
  168. data/lib/active_support/testing/setup_and_teardown.rb +6 -92
  169. data/lib/active_support/testing/tagged_logging.rb +25 -0
  170. data/lib/active_support/time.rb +6 -21
  171. data/lib/active_support/time_with_zone.rb +78 -43
  172. data/lib/active_support/values/time_zone.rb +77 -58
  173. data/lib/active_support/values/unicode_tables.dat +0 -0
  174. data/lib/active_support/version.rb +4 -4
  175. data/lib/active_support/xml_mini.rb +35 -17
  176. data/lib/active_support/xml_mini/jdom.rb +9 -17
  177. data/lib/active_support/xml_mini/libxml.rb +1 -2
  178. data/lib/active_support/xml_mini/libxmlsax.rb +1 -2
  179. data/lib/active_support/xml_mini/nokogiri.rb +1 -2
  180. data/lib/active_support/xml_mini/nokogirisax.rb +1 -2
  181. data/lib/active_support/xml_mini/rexml.rb +6 -8
  182. metadata +107 -77
  183. data/lib/active_support/base64.rb +0 -54
  184. data/lib/active_support/core_ext/array/random_access.rb +0 -30
  185. data/lib/active_support/core_ext/date/freeze.rb +0 -33
  186. data/lib/active_support/core_ext/exception.rb +0 -3
  187. data/lib/active_support/core_ext/file/path.rb +0 -5
  188. data/lib/active_support/core_ext/float.rb +0 -1
  189. data/lib/active_support/core_ext/float/rounding.rb +0 -19
  190. data/lib/active_support/core_ext/hash/deep_dup.rb +0 -18
  191. data/lib/active_support/core_ext/io.rb +0 -15
  192. data/lib/active_support/core_ext/module/method_names.rb +0 -14
  193. data/lib/active_support/core_ext/module/synchronization.rb +0 -45
  194. data/lib/active_support/core_ext/process.rb +0 -1
  195. data/lib/active_support/core_ext/process/daemon.rb +0 -23
  196. data/lib/active_support/core_ext/range/blockless_step.rb +0 -29
  197. data/lib/active_support/core_ext/range/cover.rb +0 -3
  198. data/lib/active_support/core_ext/rexml.rb +0 -46
  199. data/lib/active_support/core_ext/string/interpolation.rb +0 -2
  200. data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +0 -10
  201. data/lib/active_support/memoizable.rb +0 -116
  202. data/lib/active_support/multibyte/exceptions.rb +0 -8
  203. data/lib/active_support/multibyte/utils.rb +0 -60
  204. data/lib/active_support/ruby/shim.rb +0 -22
  205. data/lib/active_support/security_utils.rb +0 -27
  206. data/lib/active_support/testing/mochaing.rb +0 -7
  207. data/lib/active_support/testing/performance.rb +0 -317
  208. data/lib/active_support/testing/performance/jruby.rb +0 -115
  209. data/lib/active_support/testing/performance/rubinius.rb +0 -113
  210. data/lib/active_support/testing/performance/ruby.rb +0 -152
  211. data/lib/active_support/testing/performance/ruby/mri.rb +0 -57
  212. data/lib/active_support/testing/performance/ruby/yarv.rb +0 -57
  213. data/lib/active_support/time/autoload.rb +0 -5
  214. data/lib/active_support/whiny_nil.rb +0 -24
@@ -17,8 +17,8 @@ class Array
17
17
  # args.extract_options!
18
18
  # end
19
19
  #
20
- # options(1, 2) # => {}
21
- # options(1, 2, :a => :b) # => {:a=>:b}
20
+ # options(1, 2) # => {}
21
+ # options(1, 2, a: :b) # => {:a=>:b}
22
22
  def extract_options!
23
23
  if last.is_a?(Hash) && last.extractable_options?
24
24
  pop
@@ -1,21 +1,22 @@
1
- require 'enumerator'
2
-
3
1
  class Array
4
2
  # Splits or iterates over the array in groups of size +number+,
5
3
  # padding any remaining slots with +fill_with+ unless it is +false+.
6
4
  #
7
- # %w(1 2 3 4 5 6 7).in_groups_of(3) {|group| p group}
5
+ # %w(1 2 3 4 5 6 7 8 9 10).in_groups_of(3) {|group| p group}
8
6
  # ["1", "2", "3"]
9
7
  # ["4", "5", "6"]
10
- # ["7", nil, nil]
8
+ # ["7", "8", "9"]
9
+ # ["10", nil, nil]
11
10
  #
12
- # %w(1 2 3).in_groups_of(2, ' ') {|group| p group}
11
+ # %w(1 2 3 4 5).in_groups_of(2, ' ') {|group| p group}
13
12
  # ["1", "2"]
14
- # ["3", " "]
13
+ # ["3", "4"]
14
+ # ["5", " "]
15
15
  #
16
- # %w(1 2 3).in_groups_of(2, false) {|group| p group}
16
+ # %w(1 2 3 4 5).in_groups_of(2, false) {|group| p group}
17
17
  # ["1", "2"]
18
- # ["3"]
18
+ # ["3", "4"]
19
+ # ["5"]
19
20
  def in_groups_of(number, fill_with = nil)
20
21
  if fill_with == false
21
22
  collection = self
@@ -44,10 +45,10 @@ class Array
44
45
  # ["5", "6", "7", nil]
45
46
  # ["8", "9", "10", nil]
46
47
  #
47
- # %w(1 2 3 4 5 6 7).in_groups(3, ' ') {|group| p group}
48
- # ["1", "2", "3"]
49
- # ["4", "5", " "]
50
- # ["6", "7", " "]
48
+ # %w(1 2 3 4 5 6 7 8 9 10).in_groups(3, ' ') {|group| p group}
49
+ # ["1", "2", "3", "4"]
50
+ # ["5", "6", "7", " "]
51
+ # ["8", "9", "10", " "]
51
52
  #
52
53
  # %w(1 2 3 4 5 6 7).in_groups(3, false) {|group| p group}
53
54
  # ["1", "2", "3"]
@@ -57,7 +58,7 @@ class Array
57
58
  # size / number gives minor group size;
58
59
  # size % number gives how many objects need extra accommodation;
59
60
  # each group hold either division or division + 1 items.
60
- division = size / number
61
+ division = size.div number
61
62
  modulo = size % number
62
63
 
63
64
  # create a new array avoiding dup
@@ -66,9 +67,9 @@ class Array
66
67
 
67
68
  number.times do |index|
68
69
  length = division + (modulo > 0 && modulo > index ? 1 : 0)
69
- padding = fill_with != false &&
70
- modulo > 0 && length == division ? 1 : 0
71
- groups << slice(start, length).concat([fill_with] * padding)
70
+ groups << last_group = slice(start, length)
71
+ last_group << fill_with if fill_with != false &&
72
+ modulo > 0 && length == division
72
73
  start += length
73
74
  end
74
75
 
@@ -82,13 +83,11 @@ class Array
82
83
  # Divides the array into one or more subarrays based on a delimiting +value+
83
84
  # or the result of an optional block.
84
85
  #
85
- # [1, 2, 3, 4, 5].split(3) # => [[1, 2], [4, 5]]
86
- # (1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]]
87
- def split(value = nil)
88
- using_block = block_given?
89
-
86
+ # [1, 2, 3, 4, 5].split(3) # => [[1, 2], [4, 5]]
87
+ # (1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]]
88
+ def split(value = nil, &block)
90
89
  inject([[]]) do |results, element|
91
- if (using_block && yield(element)) || (value == element)
90
+ if block && block.call(element) || value == element
92
91
  results << []
93
92
  else
94
93
  results.last << element
@@ -1,16 +1,19 @@
1
1
  class Array
2
- # Returns an unique array based on the criteria given as a +Proc+.
2
+ # *DEPRECATED*: Use +Array#uniq+ instead.
3
3
  #
4
- # [1, 2, 3, 4].uniq_by { |i| i.odd? } # => [1, 2]
4
+ # Returns a unique array based on the criteria in the block.
5
5
  #
6
- def uniq_by
7
- hash, array = {}, []
8
- each { |i| hash[yield(i)] ||= (array << i) }
9
- array
6
+ # [1, 2, 3, 4].uniq_by { |i| i.odd? } # => [1, 2]
7
+ def uniq_by(&block)
8
+ ActiveSupport::Deprecation.warn 'uniq_by is deprecated. Use Array#uniq instead'
9
+ uniq(&block)
10
10
  end
11
11
 
12
- # Same as uniq_by, but modifies self.
13
- def uniq_by!
14
- replace(uniq_by{ |i| yield(i) })
12
+ # *DEPRECATED*: Use +Array#uniq!+ instead.
13
+ #
14
+ # Same as +uniq_by+, but modifies +self+.
15
+ def uniq_by!(&block)
16
+ ActiveSupport::Deprecation.warn 'uniq_by! is deprecated. Use Array#uniq! instead'
17
+ uniq!(&block)
15
18
  end
16
19
  end
@@ -7,35 +7,32 @@ class Array
7
7
  # * Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned.
8
8
  # * Otherwise, returns an array with the argument as its single element.
9
9
  #
10
- # Array.wrap(nil) # => []
11
- # Array.wrap([1, 2, 3]) # => [1, 2, 3]
12
- # Array.wrap(0) # => [0]
10
+ # Array.wrap(nil) # => []
11
+ # Array.wrap([1, 2, 3]) # => [1, 2, 3]
12
+ # Array.wrap(0) # => [0]
13
13
  #
14
14
  # This method is similar in purpose to <tt>Kernel#Array</tt>, but there are some differences:
15
15
  #
16
16
  # * If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt>
17
- # moves on to try +to_a+ if the returned value is +nil+, but <tt>Array.wrap</tt> returns
18
- # such a +nil+ right away.
17
+ # moves on to try +to_a+ if the returned value is +nil+, but <tt>Array.wrap</tt> returns
18
+ # such a +nil+ right away.
19
19
  # * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt>
20
- # raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value.
20
+ # raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value.
21
21
  # * It does not call +to_a+ on the argument, though special-cases +nil+ to return an empty array.
22
22
  #
23
23
  # The last point is particularly worth comparing for some enumerables:
24
24
  #
25
- # Array(:foo => :bar) # => [[:foo, :bar]]
26
- # Array.wrap(:foo => :bar) # => [{:foo => :bar}]
27
- #
28
- # Array("foo\nbar") # => ["foo\n", "bar"], in Ruby 1.8
29
- # Array.wrap("foo\nbar") # => ["foo\nbar"]
25
+ # Array(foo: :bar) # => [[:foo, :bar]]
26
+ # Array.wrap(foo: :bar) # => [{:foo=>:bar}]
30
27
  #
31
28
  # There's also a related idiom that uses the splat operator:
32
29
  #
33
30
  # [*object]
34
31
  #
35
- # which returns <tt>[nil]</tt> for +nil+, and calls to <tt>Array(object)</tt> otherwise.
32
+ # which for +nil+ returns <tt>[]</tt>, and calls to <tt>Array(object)</tt> otherwise.
36
33
  #
37
- # Thus, in this case the behavior is different for +nil+, and the differences with
38
- # <tt>Kernel#Array</tt> explained above apply to the rest of +object+s.
34
+ # Thus, in this case the behavior may be different for +nil+, and the differences with
35
+ # <tt>Kernel#Array</tt> explained above apply to the rest of <tt>object</tt>s.
39
36
  def self.wrap(object)
40
37
  if object.nil?
41
38
  []
@@ -1,31 +1,9 @@
1
1
  require 'bigdecimal'
2
-
3
- begin
4
- require 'psych'
5
- rescue LoadError
6
- end
7
-
8
2
  require 'yaml'
9
3
 
10
4
  class BigDecimal
11
- YAML_TAG = 'tag:yaml.org,2002:float'
12
5
  YAML_MAPPING = { 'Infinity' => '.Inf', '-Infinity' => '-.Inf', 'NaN' => '.NaN' }
13
6
 
14
- # This emits the number without any scientific notation.
15
- # This is better than self.to_f.to_s since it doesn't lose precision.
16
- #
17
- # Note that reconstituting YAML floats to native floats may lose precision.
18
- def to_yaml(opts = {})
19
- return super if
20
- (defined?(YAML::ENGINE) && !YAML::ENGINE.syck?) ||
21
- (defined?(Psych) && YAML == Psych)
22
-
23
- YAML.quick_emit(nil, opts) do |out|
24
- string = to_s
25
- out.scalar(YAML_TAG, YAML_MAPPING[string] || string, :plain)
26
- end
27
- end
28
-
29
7
  def encode_with(coder)
30
8
  string = to_s
31
9
  coder.represent_scalar(nil, YAML_MAPPING[string] || string)
@@ -39,8 +17,13 @@ class BigDecimal
39
17
  end
40
18
 
41
19
  DEFAULT_STRING_FORMAT = 'F'
42
- def to_formatted_s(format = DEFAULT_STRING_FORMAT)
43
- _original_to_s(format)
20
+ def to_formatted_s(*args)
21
+ if args[0].is_a?(Symbol)
22
+ super
23
+ else
24
+ format = args[0] || DEFAULT_STRING_FORMAT
25
+ _original_to_s(format)
26
+ end
44
27
  end
45
28
  alias_method :_original_to_s, :to_s
46
29
  alias_method :to_s, :to_formatted_s
@@ -57,19 +57,25 @@ class Class
57
57
  # object.setting # => false
58
58
  # Base.setting # => true
59
59
  #
60
- # To opt out of the instance reader method, pass :instance_reader => false.
60
+ # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
61
61
  #
62
62
  # object.setting # => NoMethodError
63
63
  # object.setting? # => NoMethodError
64
64
  #
65
- # To opt out of the instance writer method, pass :instance_writer => false.
65
+ # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
66
66
  #
67
67
  # object.setting = false # => NoMethodError
68
+ #
69
+ # To opt out of both instance methods, pass <tt>instance_accessor: false</tt>.
68
70
  def class_attribute(*attrs)
69
71
  options = attrs.extract_options!
70
- instance_reader = instance_reader = options.fetch(:instance_reader, true)
71
- instance_writer = options.fetch(:instance_writer, true)
72
+ # double assignment is used to avoid "assigned but unused variable" warning
73
+ instance_reader = instance_reader = options.fetch(:instance_accessor, true) && options.fetch(:instance_reader, true)
74
+ instance_writer = options.fetch(:instance_accessor, true) && options.fetch(:instance_writer, true)
72
75
 
76
+ # We use class_eval here rather than define_method because class_attribute
77
+ # may be used in a performance sensitive context therefore the overhead that
78
+ # define_method introduces may become significant.
73
79
  attrs.each do |name|
74
80
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
75
81
  def self.#{name}() nil end
@@ -109,9 +115,7 @@ class Class
109
115
  end
110
116
 
111
117
  private
112
- unless respond_to?(:singleton_class?)
113
- def singleton_class?
114
- ancestors.first != self
115
- end
118
+ def singleton_class?
119
+ ancestors.first != self
116
120
  end
117
121
  end
@@ -21,17 +21,18 @@ class Class
21
21
  # end
22
22
  # # => NameError: invalid attribute name
23
23
  #
24
- # If you want to opt out the instance reader method, you can pass <tt>:instance_reader => false</tt>
25
- # or <tt>:instance_accessor => false</tt>.
24
+ # If you want to opt out the instance reader method, you can pass <tt>instance_reader: false</tt>
25
+ # or <tt>instance_accessor: false</tt>.
26
26
  #
27
27
  # class Person
28
- # cattr_reader :hair_colors, :instance_reader => false
28
+ # cattr_reader :hair_colors, instance_reader: false
29
29
  # end
30
30
  #
31
31
  # Person.new.hair_colors # => NoMethodError
32
32
  def cattr_reader(*syms)
33
33
  options = syms.extract_options!
34
34
  syms.each do |sym|
35
+ raise NameError.new('invalid attribute name') unless sym =~ /^[_A-Za-z]\w*$/
35
36
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
36
37
  unless defined? @@#{sym}
37
38
  @@#{sym} = nil
@@ -71,11 +72,11 @@ class Class
71
72
  # end
72
73
  # # => NameError: invalid attribute name
73
74
  #
74
- # If you want to opt out the instance writer method, pass <tt>:instance_writer => false</tt>
75
- # or <tt>:instance_accessor => false</tt>.
75
+ # If you want to opt out the instance writer method, pass <tt>instance_writer: false</tt>
76
+ # or <tt>instance_accessor: false</tt>.
76
77
  #
77
78
  # class Person
78
- # cattr_writer :hair_colors, :instance_writer => false
79
+ # cattr_writer :hair_colors, instance_writer: false
79
80
  # end
80
81
  #
81
82
  # Person.new.hair_colors = [:blonde, :red] # => NoMethodError
@@ -92,6 +93,7 @@ class Class
92
93
  def cattr_writer(*syms)
93
94
  options = syms.extract_options!
94
95
  syms.each do |sym|
96
+ raise NameError.new('invalid attribute name') unless sym =~ /^[_A-Za-z]\w*$/
95
97
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
96
98
  unless defined? @@#{sym}
97
99
  @@#{sym} = nil
@@ -109,7 +111,7 @@ class Class
109
111
  end
110
112
  EOS
111
113
  end
112
- self.send("#{sym}=", yield) if block_given?
114
+ send("#{sym}=", yield) if block_given?
113
115
  end
114
116
  end
115
117
 
@@ -133,20 +135,20 @@ class Class
133
135
  # Male.hair_colors << :blue
134
136
  # Person.hair_colors # => [:brown, :black, :blonde, :red, :blue]
135
137
  #
136
- # To opt out of the instance writer method, pass <tt>:instance_writer => false</tt>.
137
- # To opt out of the instance reader method, pass <tt>:instance_reader => false</tt>.
138
+ # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
139
+ # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
138
140
  #
139
141
  # class Person
140
- # cattr_accessor :hair_colors, :instance_writer => false, :instance_reader => false
142
+ # cattr_accessor :hair_colors, instance_writer: false, instance_reader: false
141
143
  # end
142
144
  #
143
145
  # Person.new.hair_colors = [:brown] # => NoMethodError
144
146
  # Person.new.hair_colors # => NoMethodError
145
147
  #
146
- # Or pass <tt>:instance_accessor => false</tt>, to opt out both instance methods.
148
+ # Or pass <tt>instance_accessor: false</tt>, to opt out both instance methods.
147
149
  #
148
150
  # class Person
149
- # cattr_accessor :hair_colors, :instance_accessor => false
151
+ # cattr_accessor :hair_colors, instance_accessor: false
150
152
  # end
151
153
  #
152
154
  # Person.new.hair_colors = [:brown] # => NoMethodError
@@ -1,5 +1,3 @@
1
- require 'active_support/core_ext/object/blank'
2
- require 'active_support/core_ext/array/extract_options'
3
1
  require 'active_support/core_ext/kernel/singleton_class'
4
2
  require 'active_support/core_ext/module/remove_method'
5
3
 
@@ -22,23 +20,21 @@ class Class
22
20
  define_method("#{name}?") { !!send("#{name}") } if options[:instance_reader] != false
23
21
  end
24
22
 
25
- private
26
-
27
- # Take the object being set and store it in a method. This gives us automatic
28
- # inheritance behavior, without having to store the object in an instance
29
- # variable and look up the superclass chain manually.
30
- def _stash_object_in_method(object, method, instance_reader = true)
31
- singleton_class.remove_possible_method(method)
32
- singleton_class.send(:define_method, method) { object }
33
- remove_possible_method(method)
34
- define_method(method) { object } if instance_reader
35
- end
36
-
37
- def _superclass_delegating_accessor(name, options = {})
38
- singleton_class.send(:define_method, "#{name}=") do |value|
39
- _stash_object_in_method(value, name, options[:instance_reader] != false)
23
+ private
24
+ # Take the object being set and store it in a method. This gives us automatic
25
+ # inheritance behavior, without having to store the object in an instance
26
+ # variable and look up the superclass chain manually.
27
+ def _stash_object_in_method(object, method, instance_reader = true)
28
+ singleton_class.remove_possible_method(method)
29
+ singleton_class.send(:define_method, method) { object }
30
+ remove_possible_method(method)
31
+ define_method(method) { object } if instance_reader
40
32
  end
41
- send("#{name}=", nil)
42
- end
43
33
 
34
+ def _superclass_delegating_accessor(name, options = {})
35
+ singleton_class.send(:define_method, "#{name}=") do |value|
36
+ _stash_object_in_method(value, name, options[:instance_reader] != false)
37
+ end
38
+ send("#{name}=", nil)
39
+ end
44
40
  end
@@ -1,19 +1,19 @@
1
1
  require 'active_support/core_ext/module/anonymous'
2
2
  require 'active_support/core_ext/module/reachable'
3
3
 
4
- class Class #:nodoc:
4
+ class Class
5
5
  begin
6
6
  ObjectSpace.each_object(Class.new) {}
7
7
 
8
- def descendants
8
+ def descendants # :nodoc:
9
9
  descendants = []
10
- ObjectSpace.each_object(class << self; self; end) do |k|
10
+ ObjectSpace.each_object(singleton_class) do |k|
11
11
  descendants.unshift k unless k == self
12
12
  end
13
13
  descendants
14
14
  end
15
15
  rescue StandardError # JRuby
16
- def descendants
16
+ def descendants # :nodoc:
17
17
  descendants = []
18
18
  ObjectSpace.each_object(Class) do |k|
19
19
  descendants.unshift k if k < self
@@ -25,7 +25,13 @@ class Class #:nodoc:
25
25
 
26
26
  # Returns an array with the direct children of +self+.
27
27
  #
28
- # Integer.subclasses # => [Bignum, Fixnum]
28
+ # Integer.subclasses # => [Fixnum, Bignum]
29
+ #
30
+ # class Foo; end
31
+ # class Bar < Foo; end
32
+ # class Baz < Bar; end
33
+ #
34
+ # Foo.subclasses # => [Bar]
29
35
  def subclasses
30
36
  subclasses, chain = [], descendants
31
37
  chain.each do |k|
@@ -0,0 +1,6 @@
1
+ require 'active_support/core_ext/date/acts_like'
2
+ require 'active_support/core_ext/date/calculations'
3
+ require 'active_support/core_ext/date/conversions'
4
+ require 'active_support/core_ext/date/zones'
5
+ require 'active_support/core_ext/date/infinite_comparable'
6
+
@@ -3,29 +3,35 @@ require 'active_support/duration'
3
3
  require 'active_support/core_ext/object/acts_like'
4
4
  require 'active_support/core_ext/date/zones'
5
5
  require 'active_support/core_ext/time/zones'
6
+ require 'active_support/core_ext/date_and_time/calculations'
6
7
 
7
8
  class Date
8
- DAYS_INTO_WEEK = { :monday => 0, :tuesday => 1, :wednesday => 2, :thursday => 3, :friday => 4, :saturday => 5, :sunday => 6 }
9
+ include DateAndTime::Calculations
9
10
 
10
- if RUBY_VERSION < '1.9'
11
- undef :>>
11
+ class << self
12
+ attr_accessor :beginning_of_week_default
12
13
 
13
- # Backported from 1.9. The one in 1.8 leads to incorrect next_month and
14
- # friends for dates where the calendar reform is involved. It additionally
15
- # prevents an infinite loop fixed in r27013.
16
- def >>(n)
17
- y, m = (year * 12 + (mon - 1) + n).divmod(12)
18
- m, = (m + 1) .divmod(1)
19
- d = mday
20
- until jd2 = self.class.valid_civil?(y, m, d, start)
21
- d -= 1
22
- raise ArgumentError, 'invalid date' unless d > 0
23
- end
24
- self + (jd2 - jd)
14
+ # Returns the week start (e.g. :monday) for the current request, if this has been set (via Date.beginning_of_week=).
15
+ # If <tt>Date.beginning_of_week</tt> has not been set for the current request, returns the week start specified in <tt>config.beginning_of_week</tt>.
16
+ # If no config.beginning_of_week was specified, returns :monday.
17
+ def beginning_of_week
18
+ Thread.current[:beginning_of_week] || beginning_of_week_default || :monday
19
+ end
20
+
21
+ # Sets <tt>Date.beginning_of_week</tt> to a week start (e.g. :monday) for current request/thread.
22
+ #
23
+ # This method accepts any of the following day symbols:
24
+ # :monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday
25
+ def beginning_of_week=(week_start)
26
+ Thread.current[:beginning_of_week] = find_beginning_of_week!(week_start)
27
+ end
28
+
29
+ # Returns week start day symbol (e.g. :monday), or raises an ArgumentError for invalid day symbol.
30
+ def find_beginning_of_week!(week_start)
31
+ raise ArgumentError, "Invalid beginning of week: #{week_start}" unless ::Date::DAYS_INTO_WEEK.key?(week_start)
32
+ week_start
25
33
  end
26
- end
27
34
 
28
- class << self
29
35
  # Returns a new Date representing the date 1 day ago (i.e. yesterday's date).
30
36
  def yesterday
31
37
  ::Date.current.yesterday
@@ -42,37 +48,22 @@ class Date
42
48
  end
43
49
  end
44
50
 
45
- # Returns true if the Date object's date lies in the past. Otherwise returns false.
46
- def past?
47
- self < ::Date.current
48
- end
49
-
50
- # Returns true if the Date object's date is today.
51
- def today?
52
- self.to_date == ::Date.current # we need the to_date because of DateTime
53
- end
54
-
55
- # Returns true if the Date object's date lies in the future.
56
- def future?
57
- self > ::Date.current
58
- end
59
-
60
51
  # Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
61
52
  # and then subtracts the specified number of seconds.
62
53
  def ago(seconds)
63
- to_time_in_current_zone.since(-seconds)
54
+ in_time_zone.since(-seconds)
64
55
  end
65
56
 
66
57
  # Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
67
58
  # and then adds the specified number of seconds
68
59
  def since(seconds)
69
- to_time_in_current_zone.since(seconds)
60
+ in_time_zone.since(seconds)
70
61
  end
71
62
  alias :in :since
72
63
 
73
64
  # Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
74
65
  def beginning_of_day
75
- to_time_in_current_zone
66
+ in_time_zone
76
67
  end
77
68
  alias :midnight :beginning_of_day
78
69
  alias :at_midnight :beginning_of_day
@@ -80,8 +71,9 @@ class Date
80
71
 
81
72
  # Converts Date to a Time (or DateTime if necessary) with the time portion set to the end of the day (23:59:59)
82
73
  def end_of_day
83
- to_time_in_current_zone.end_of_day
74
+ in_time_zone.end_of_day
84
75
  end
76
+ alias :at_end_of_day :end_of_day
85
77
 
86
78
  def plus_with_duration(other) #:nodoc:
87
79
  if ActiveSupport::Duration === other
@@ -116,161 +108,15 @@ class Date
116
108
  end
117
109
 
118
110
  # Returns a new Date where one or more of the elements have been changed according to the +options+ parameter.
111
+ # The +options+ parameter is a hash with a combination of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>.
119
112
  #
120
- # Examples:
121
- #
122
- # Date.new(2007, 5, 12).change(:day => 1) # => Date.new(2007, 5, 1)
123
- # Date.new(2007, 5, 12).change(:year => 2005, :month => 1) # => Date.new(2005, 1, 12)
113
+ # Date.new(2007, 5, 12).change(day: 1) # => Date.new(2007, 5, 1)
114
+ # Date.new(2007, 5, 12).change(year: 2005, month: 1) # => Date.new(2005, 1, 12)
124
115
  def change(options)
125
116
  ::Date.new(
126
- options[:year] || self.year,
127
- options[:month] || self.month,
128
- options[:day] || self.day
117
+ options.fetch(:year, year),
118
+ options.fetch(:month, month),
119
+ options.fetch(:day, day)
129
120
  )
130
121
  end
131
-
132
- # Returns a new Date/DateTime representing the time a number of specified weeks ago.
133
- def weeks_ago(weeks)
134
- advance(:weeks => -weeks)
135
- end
136
-
137
- # Returns a new Date/DateTime representing the time a number of specified months ago.
138
- def months_ago(months)
139
- advance(:months => -months)
140
- end
141
-
142
- # Returns a new Date/DateTime representing the time a number of specified months in the future.
143
- def months_since(months)
144
- advance(:months => months)
145
- end
146
-
147
- # Returns a new Date/DateTime representing the time a number of specified years ago.
148
- def years_ago(years)
149
- advance(:years => -years)
150
- end
151
-
152
- # Returns a new Date/DateTime representing the time a number of specified years in the future.
153
- def years_since(years)
154
- advance(:years => years)
155
- end
156
-
157
- # Shorthand for years_ago(1)
158
- def prev_year
159
- years_ago(1)
160
- end unless method_defined?(:prev_year)
161
-
162
- # Shorthand for years_since(1)
163
- def next_year
164
- years_since(1)
165
- end unless method_defined?(:next_year)
166
-
167
- # Shorthand for months_ago(1)
168
- def prev_month
169
- months_ago(1)
170
- end unless method_defined?(:prev_month)
171
-
172
- # Shorthand for months_since(1)
173
- def next_month
174
- months_since(1)
175
- end unless method_defined?(:next_month)
176
-
177
- # Returns number of days to start of this week. Week is assumed to start on
178
- # +start_day+, default is +:monday+.
179
- def days_to_week_start(start_day = :monday)
180
- start_day_number = DAYS_INTO_WEEK[start_day]
181
- current_day_number = wday != 0 ? wday - 1 : 6
182
- (current_day_number - start_day_number) % 7
183
- end
184
-
185
- # Returns a new +Date+/+DateTime+ representing the start of this week. Week is
186
- # assumed to start on +start_day+, default is +:monday+. +DateTime+ objects
187
- # have their time set to 0:00.
188
- def beginning_of_week(start_day = :monday)
189
- days_to_start = days_to_week_start(start_day)
190
- result = self - days_to_start
191
- acts_like?(:time) ? result.midnight : result
192
- end
193
- alias :at_beginning_of_week :beginning_of_week
194
-
195
- # Returns a new +Date+/+DateTime+ representing the start of this week. Week is
196
- # assumed to start on a Monday. +DateTime+ objects have their time set to 0:00.
197
- def monday
198
- beginning_of_week
199
- end
200
-
201
- # Returns a new +Date+/+DateTime+ representing the end of this week. Week is
202
- # assumed to start on +start_day+, default is +:monday+. +DateTime+ objects
203
- # have their time set to 23:59:59.
204
- def end_of_week(start_day = :monday)
205
- days_to_end = 6 - days_to_week_start(start_day)
206
- result = self + days_to_end.days
207
- self.acts_like?(:time) ? result.end_of_day : result
208
- end
209
- alias :at_end_of_week :end_of_week
210
-
211
- # Returns a new +Date+/+DateTime+ representing the end of this week. Week is
212
- # assumed to start on a Monday. +DateTime+ objects have their time set to 23:59:59.
213
- def sunday
214
- end_of_week
215
- end
216
-
217
- # Returns a new +Date+/+DateTime+ representing the given +day+ in the previous
218
- # week. Default is +:monday+. +DateTime+ objects have their time set to 0:00.
219
- def prev_week(day = :monday)
220
- result = (self - 7).beginning_of_week + DAYS_INTO_WEEK[day]
221
- self.acts_like?(:time) ? result.change(:hour => 0) : result
222
- end
223
-
224
- # Returns a new Date/DateTime representing the start of the given day in next week (default is :monday).
225
- def next_week(day = :monday)
226
- result = (self + 7).beginning_of_week + DAYS_INTO_WEEK[day]
227
- self.acts_like?(:time) ? result.change(:hour => 0) : result
228
- end
229
-
230
- # Returns a new ; DateTime objects will have time set to 0:00DateTime representing the start of the month (1st of the month; DateTime objects will have time set to 0:00)
231
- def beginning_of_month
232
- self.acts_like?(:time) ? change(:day => 1, :hour => 0) : change(:day => 1)
233
- end
234
- alias :at_beginning_of_month :beginning_of_month
235
-
236
- # Returns a new Date/DateTime representing the end of the month (last day of the month; DateTime objects will have time set to 0:00)
237
- def end_of_month
238
- last_day = ::Time.days_in_month( self.month, self.year )
239
- self.acts_like?(:time) ? change(:day => last_day, :hour => 23, :min => 59, :sec => 59) : change(:day => last_day)
240
- end
241
- alias :at_end_of_month :end_of_month
242
-
243
- # Returns a new Date/DateTime representing the start of the quarter (1st of january, april, july, october; DateTime objects will have time set to 0:00)
244
- def beginning_of_quarter
245
- beginning_of_month.change(:month => [10, 7, 4, 1].detect { |m| m <= self.month })
246
- end
247
- alias :at_beginning_of_quarter :beginning_of_quarter
248
-
249
- # Returns a new Date/DateTime representing the end of the quarter (last day of march, june, september, december; DateTime objects will have time set to 23:59:59)
250
- def end_of_quarter
251
- beginning_of_month.change(:month => [3, 6, 9, 12].detect { |m| m >= self.month }).end_of_month
252
- end
253
- alias :at_end_of_quarter :end_of_quarter
254
-
255
- # Returns a new Date/DateTime representing the start of the year (1st of january; DateTime objects will have time set to 0:00)
256
- def beginning_of_year
257
- self.acts_like?(:time) ? change(:month => 1, :day => 1, :hour => 0) : change(:month => 1, :day => 1)
258
- end
259
- alias :at_beginning_of_year :beginning_of_year
260
-
261
- # Returns a new Time representing the end of the year (31st of december; DateTime objects will have time set to 23:59:59)
262
- def end_of_year
263
- self.acts_like?(:time) ? change(:month => 12, :day => 31, :hour => 23, :min => 59, :sec => 59) : change(:month => 12, :day => 31)
264
- end
265
- alias :at_end_of_year :end_of_year
266
-
267
- # Convenience method which returns a new Date/DateTime representing the time 1 day ago
268
- def yesterday
269
- self - 1
270
- end
271
-
272
- # Convenience method which returns a new Date/DateTime representing the time 1 day since the instance time
273
- def tomorrow
274
- self + 1
275
- end
276
122
  end