activesupport 4.0.13 → 4.2.11.3

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 (166) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +406 -418
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +7 -2
  5. data/lib/active_support/backtrace_cleaner.rb +8 -8
  6. data/lib/active_support/benchmarkable.rb +0 -10
  7. data/lib/active_support/cache/file_store.rb +32 -22
  8. data/lib/active_support/cache/mem_cache_store.rb +5 -7
  9. data/lib/active_support/cache/memory_store.rb +1 -0
  10. data/lib/active_support/cache/strategy/local_cache.rb +11 -30
  11. data/lib/active_support/cache/strategy/local_cache_middleware.rb +44 -0
  12. data/lib/active_support/cache.rb +75 -41
  13. data/lib/active_support/callbacks.rb +482 -261
  14. data/lib/active_support/concern.rb +23 -7
  15. data/lib/active_support/configurable.rb +1 -1
  16. data/lib/active_support/core_ext/array/access.rb +11 -1
  17. data/lib/active_support/core_ext/array/conversions.rb +2 -17
  18. data/lib/active_support/core_ext/array/grouping.rb +29 -12
  19. data/lib/active_support/core_ext/array/prepend_and_append.rb +2 -2
  20. data/lib/active_support/core_ext/array.rb +0 -1
  21. data/lib/active_support/core_ext/big_decimal/conversions.rb +0 -15
  22. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +16 -0
  23. data/lib/active_support/core_ext/class/attribute.rb +1 -2
  24. data/lib/active_support/core_ext/class/attribute_accessors.rb +4 -170
  25. data/lib/active_support/core_ext/class/delegating_attributes.rb +13 -8
  26. data/lib/active_support/core_ext/class/subclasses.rb +0 -2
  27. data/lib/active_support/core_ext/class.rb +0 -1
  28. data/lib/active_support/core_ext/date/calculations.rb +10 -0
  29. data/lib/active_support/core_ext/date/conversions.rb +9 -1
  30. data/lib/active_support/core_ext/date/zones.rb +2 -33
  31. data/lib/active_support/core_ext/date_and_time/calculations.rb +41 -11
  32. data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
  33. data/lib/active_support/core_ext/date_and_time/zones.rb +41 -0
  34. data/lib/active_support/core_ext/date_time/calculations.rb +45 -22
  35. data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
  36. data/lib/active_support/core_ext/date_time/conversions.rb +4 -2
  37. data/lib/active_support/core_ext/date_time/zones.rb +3 -21
  38. data/lib/active_support/core_ext/date_time.rb +1 -0
  39. data/lib/active_support/core_ext/digest/uuid.rb +51 -0
  40. data/lib/active_support/core_ext/enumerable.rb +17 -1
  41. data/lib/active_support/core_ext/file/atomic.rb +1 -1
  42. data/lib/active_support/core_ext/hash/compact.rb +24 -0
  43. data/lib/active_support/core_ext/hash/conversions.rb +9 -8
  44. data/lib/active_support/core_ext/hash/except.rb +8 -2
  45. data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -0
  46. data/lib/active_support/core_ext/hash/keys.rb +25 -19
  47. data/lib/active_support/core_ext/hash/slice.rb +8 -2
  48. data/lib/active_support/core_ext/hash/transform_values.rb +23 -0
  49. data/lib/active_support/core_ext/hash.rb +2 -1
  50. data/lib/active_support/core_ext/integer/time.rb +0 -15
  51. data/lib/active_support/core_ext/kernel/concern.rb +10 -0
  52. data/lib/active_support/core_ext/kernel/debugger.rb +1 -1
  53. data/lib/active_support/core_ext/kernel/reporting.rb +13 -2
  54. data/lib/active_support/core_ext/kernel.rb +3 -2
  55. data/lib/active_support/core_ext/load_error.rb +4 -1
  56. data/lib/active_support/core_ext/marshal.rb +8 -5
  57. data/lib/active_support/core_ext/module/aliasing.rb +2 -2
  58. data/lib/active_support/core_ext/module/attr_internal.rb +2 -1
  59. data/lib/active_support/core_ext/module/attribute_accessors.rb +160 -14
  60. data/lib/active_support/core_ext/module/concerning.rb +135 -0
  61. data/lib/active_support/core_ext/module/delegation.rb +53 -25
  62. data/lib/active_support/core_ext/module/deprecation.rb +0 -2
  63. data/lib/active_support/core_ext/module/introspection.rb +0 -16
  64. data/lib/active_support/core_ext/module/method_transplanting.rb +13 -0
  65. data/lib/active_support/core_ext/module.rb +1 -0
  66. data/lib/active_support/core_ext/numeric/conversions.rb +11 -3
  67. data/lib/active_support/core_ext/numeric/time.rb +4 -29
  68. data/lib/active_support/core_ext/object/blank.rb +44 -18
  69. data/lib/active_support/core_ext/object/deep_dup.rb +6 -6
  70. data/lib/active_support/core_ext/object/duplicable.rb +72 -33
  71. data/lib/active_support/core_ext/object/inclusion.rb +16 -15
  72. data/lib/active_support/core_ext/object/itself.rb +15 -0
  73. data/lib/active_support/core_ext/object/json.rb +197 -0
  74. data/lib/active_support/core_ext/object/to_query.rb +14 -6
  75. data/lib/active_support/core_ext/object/try.rb +36 -14
  76. data/lib/active_support/core_ext/object/with_options.rb +30 -3
  77. data/lib/active_support/core_ext/object.rb +2 -1
  78. data/lib/active_support/core_ext/string/access.rb +35 -35
  79. data/lib/active_support/core_ext/string/conversions.rb +10 -9
  80. data/lib/active_support/core_ext/string/exclude.rb +3 -3
  81. data/lib/active_support/core_ext/string/filters.rb +51 -3
  82. data/lib/active_support/core_ext/string/inflections.rb +15 -10
  83. data/lib/active_support/core_ext/string/output_safety.rb +97 -33
  84. data/lib/active_support/core_ext/string/zones.rb +1 -0
  85. data/lib/active_support/core_ext/thread.rb +12 -5
  86. data/lib/active_support/core_ext/time/calculations.rb +47 -68
  87. data/lib/active_support/core_ext/time/compatibility.rb +14 -0
  88. data/lib/active_support/core_ext/time/conversions.rb +4 -2
  89. data/lib/active_support/core_ext/time/zones.rb +2 -20
  90. data/lib/active_support/core_ext/time.rb +1 -0
  91. data/lib/active_support/core_ext.rb +0 -1
  92. data/lib/active_support/dependencies/autoload.rb +1 -1
  93. data/lib/active_support/dependencies.rb +64 -25
  94. data/lib/active_support/deprecation/behaviors.rb +4 -4
  95. data/lib/active_support/deprecation.rb +4 -4
  96. data/lib/active_support/duration.rb +55 -11
  97. data/lib/active_support/file_update_checker.rb +1 -1
  98. data/lib/active_support/gem_version.rb +15 -0
  99. data/lib/active_support/hash_with_indifferent_access.rb +39 -11
  100. data/lib/active_support/i18n.rb +4 -4
  101. data/lib/active_support/i18n_railtie.rb +1 -7
  102. data/lib/active_support/inflections.rb +6 -1
  103. data/lib/active_support/inflector/inflections.rb +19 -19
  104. data/lib/active_support/inflector/methods.rb +66 -25
  105. data/lib/active_support/json/decoding.rb +15 -22
  106. data/lib/active_support/json/encoding.rb +125 -286
  107. data/lib/active_support/key_generator.rb +8 -10
  108. data/lib/active_support/lazy_load_hooks.rb +1 -1
  109. data/lib/active_support/log_subscriber/test_helper.rb +1 -1
  110. data/lib/active_support/logger.rb +51 -1
  111. data/lib/active_support/logger_silence.rb +7 -4
  112. data/lib/active_support/logger_thread_safe_level.rb +32 -0
  113. data/lib/active_support/message_encryptor.rb +14 -6
  114. data/lib/active_support/message_verifier.rb +16 -12
  115. data/lib/active_support/multibyte/chars.rb +2 -3
  116. data/lib/active_support/multibyte/unicode.rb +46 -58
  117. data/lib/active_support/notifications/fanout.rb +12 -7
  118. data/lib/active_support/notifications/instrumenter.rb +2 -1
  119. data/lib/active_support/notifications.rb +11 -6
  120. data/lib/active_support/number_helper/number_converter.rb +182 -0
  121. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  122. data/lib/active_support/number_helper/number_to_delimited_converter.rb +23 -0
  123. data/lib/active_support/number_helper/number_to_human_converter.rb +66 -0
  124. data/lib/active_support/number_helper/number_to_human_size_converter.rb +58 -0
  125. data/lib/active_support/number_helper/number_to_percentage_converter.rb +12 -0
  126. data/lib/active_support/number_helper/number_to_phone_converter.rb +49 -0
  127. data/lib/active_support/number_helper/number_to_rounded_converter.rb +87 -0
  128. data/lib/active_support/number_helper.rb +32 -324
  129. data/lib/active_support/ordered_options.rb +8 -0
  130. data/lib/active_support/per_thread_registry.rb +13 -10
  131. data/lib/active_support/security_utils.rb +27 -0
  132. data/lib/active_support/subscriber.rb +35 -3
  133. data/lib/active_support/test_case.rb +52 -19
  134. data/lib/active_support/testing/assertions.rb +1 -31
  135. data/lib/active_support/testing/autorun.rb +2 -2
  136. data/lib/active_support/testing/constant_lookup.rb +1 -5
  137. data/lib/active_support/testing/declarative.rb +7 -21
  138. data/lib/active_support/testing/isolation.rb +29 -69
  139. data/lib/active_support/testing/setup_and_teardown.rb +17 -2
  140. data/lib/active_support/testing/tagged_logging.rb +2 -2
  141. data/lib/active_support/testing/time_helpers.rb +134 -0
  142. data/lib/active_support/time.rb +0 -2
  143. data/lib/active_support/time_with_zone.rb +60 -40
  144. data/lib/active_support/values/time_zone.rb +101 -101
  145. data/lib/active_support/values/unicode_tables.dat +0 -0
  146. data/lib/active_support/version.rb +4 -7
  147. data/lib/active_support/xml_mini/jdom.rb +6 -5
  148. data/lib/active_support/xml_mini/libxml.rb +1 -3
  149. data/lib/active_support/xml_mini/libxmlsax.rb +1 -4
  150. data/lib/active_support/xml_mini/nokogiri.rb +1 -3
  151. data/lib/active_support/xml_mini/nokogirisax.rb +1 -3
  152. data/lib/active_support/xml_mini/rexml.rb +7 -8
  153. data/lib/active_support/xml_mini.rb +33 -15
  154. data/lib/active_support.rb +27 -2
  155. metadata +43 -43
  156. data/lib/active_support/basic_object.rb +0 -11
  157. data/lib/active_support/buffered_logger.rb +0 -21
  158. data/lib/active_support/core_ext/array/uniq_by.rb +0 -19
  159. data/lib/active_support/core_ext/hash/diff.rb +0 -14
  160. data/lib/active_support/core_ext/logger.rb +0 -67
  161. data/lib/active_support/core_ext/object/to_json.rb +0 -27
  162. data/lib/active_support/core_ext/proc.rb +0 -17
  163. data/lib/active_support/core_ext/string/encoding.rb +0 -8
  164. data/lib/active_support/file_watcher.rb +0 -36
  165. data/lib/active_support/json/variable.rb +0 -18
  166. data/lib/active_support/testing/pending.rb +0 -14
@@ -1,12 +1,13 @@
1
1
  class Hash
2
- # Return a new hash with all keys converted using the block operation.
2
+ # Returns a new hash with all keys converted using the block operation.
3
3
  #
4
4
  # hash = { name: 'Rob', age: '28' }
5
5
  #
6
6
  # hash.transform_keys{ |key| key.to_s.upcase }
7
- # # => { "NAME" => "Rob", "AGE" => "28" }
7
+ # # => {"NAME"=>"Rob", "AGE"=>"28"}
8
8
  def transform_keys
9
- result = {}
9
+ return enum_for(:transform_keys) unless block_given?
10
+ result = self.class.new
10
11
  each_key do |key|
11
12
  result[yield(key)] = self[key]
12
13
  end
@@ -16,18 +17,19 @@ class Hash
16
17
  # Destructively convert all keys using the block operations.
17
18
  # Same as transform_keys but modifies +self+.
18
19
  def transform_keys!
20
+ return enum_for(:transform_keys!) unless block_given?
19
21
  keys.each do |key|
20
22
  self[yield(key)] = delete(key)
21
23
  end
22
24
  self
23
25
  end
24
26
 
25
- # Return a new hash with all keys converted to strings.
27
+ # Returns a new hash with all keys converted to strings.
26
28
  #
27
29
  # hash = { name: 'Rob', age: '28' }
28
30
  #
29
31
  # hash.stringify_keys
30
- # #=> { "name" => "Rob", "age" => "28" }
32
+ # # => {"name"=>"Rob", "age"=>"28"}
31
33
  def stringify_keys
32
34
  transform_keys{ |key| key.to_s }
33
35
  end
@@ -38,13 +40,13 @@ class Hash
38
40
  transform_keys!{ |key| key.to_s }
39
41
  end
40
42
 
41
- # Return a new hash with all keys converted to symbols, as long as
43
+ # Returns a new hash with all keys converted to symbols, as long as
42
44
  # they respond to +to_sym+.
43
45
  #
44
46
  # hash = { 'name' => 'Rob', 'age' => '28' }
45
47
  #
46
48
  # hash.symbolize_keys
47
- # #=> { name: "Rob", age: "28" }
49
+ # # => {:name=>"Rob", :age=>"28"}
48
50
  def symbolize_keys
49
51
  transform_keys{ |key| key.to_sym rescue key }
50
52
  end
@@ -57,28 +59,32 @@ class Hash
57
59
  end
58
60
  alias_method :to_options!, :symbolize_keys!
59
61
 
60
- # Validate all keys in a hash match <tt>*valid_keys</tt>, raising ArgumentError
61
- # on a mismatch. Note that keys are NOT treated indifferently, meaning if you
62
- # use strings for keys but assert symbols as keys, this will fail.
62
+ # Validate all keys in a hash match <tt>*valid_keys</tt>, raising
63
+ # ArgumentError on a mismatch.
63
64
  #
64
- # { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: years"
65
- # { name: 'Rob', age: '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: name"
65
+ # Note that keys are treated differently than HashWithIndifferentAccess,
66
+ # meaning that string and symbol keys will not match.
67
+ #
68
+ # { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: :years. Valid keys are: :name, :age"
69
+ # { name: 'Rob', age: '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: :name. Valid keys are: 'name', 'age'"
66
70
  # { name: 'Rob', age: '28' }.assert_valid_keys(:name, :age) # => passes, raises nothing
67
71
  def assert_valid_keys(*valid_keys)
68
72
  valid_keys.flatten!
69
73
  each_key do |k|
70
- raise ArgumentError.new("Unknown key: #{k}") unless valid_keys.include?(k)
74
+ unless valid_keys.include?(k)
75
+ raise ArgumentError.new("Unknown key: #{k.inspect}. Valid keys are: #{valid_keys.map(&:inspect).join(', ')}")
76
+ end
71
77
  end
72
78
  end
73
79
 
74
- # Return a new hash with all keys converted by the block operation.
80
+ # Returns a new hash with all keys converted by the block operation.
75
81
  # This includes the keys from the root hash and from all
76
82
  # nested hashes and arrays.
77
83
  #
78
84
  # hash = { person: { name: 'Rob', age: '28' } }
79
85
  #
80
86
  # hash.deep_transform_keys{ |key| key.to_s.upcase }
81
- # # => { "PERSON" => { "NAME" => "Rob", "AGE" => "28" } }
87
+ # # => {"PERSON"=>{"NAME"=>"Rob", "AGE"=>"28"}}
82
88
  def deep_transform_keys(&block)
83
89
  _deep_transform_keys_in_object(self, &block)
84
90
  end
@@ -90,14 +96,14 @@ class Hash
90
96
  _deep_transform_keys_in_object!(self, &block)
91
97
  end
92
98
 
93
- # Return a new hash with all keys converted to strings.
99
+ # Returns a new hash with all keys converted to strings.
94
100
  # This includes the keys from the root hash and from all
95
101
  # nested hashes and arrays.
96
102
  #
97
103
  # hash = { person: { name: 'Rob', age: '28' } }
98
104
  #
99
105
  # hash.deep_stringify_keys
100
- # # => { "person" => { "name" => "Rob", "age" => "28" } }
106
+ # # => {"person"=>{"name"=>"Rob", "age"=>"28"}}
101
107
  def deep_stringify_keys
102
108
  deep_transform_keys{ |key| key.to_s }
103
109
  end
@@ -109,14 +115,14 @@ class Hash
109
115
  deep_transform_keys!{ |key| key.to_s }
110
116
  end
111
117
 
112
- # Return a new hash with all keys converted to symbols, as long as
118
+ # Returns a new hash with all keys converted to symbols, as long as
113
119
  # they respond to +to_sym+. This includes the keys from the root hash
114
120
  # and from all nested hashes and arrays.
115
121
  #
116
122
  # hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } }
117
123
  #
118
124
  # hash.deep_symbolize_keys
119
- # # => { person: { name: "Rob", age: "28" } }
125
+ # # => {:person=>{:name=>"Rob", :age=>"28"}}
120
126
  def deep_symbolize_keys
121
127
  deep_transform_keys{ |key| key.to_sym rescue key }
122
128
  end
@@ -1,6 +1,12 @@
1
1
  class Hash
2
- # Slice a hash to include only the given keys. This is useful for
3
- # limiting an options hash to valid keys before passing to a method:
2
+ # Slice a hash to include only the given keys. Returns a hash containing
3
+ # the given keys.
4
+ #
5
+ # { a: 1, b: 2, c: 3, d: 4 }.slice(:a, :b)
6
+ # # => {:a=>1, :b=>2}
7
+ #
8
+ # This is useful for limiting an options hash to valid keys before
9
+ # passing to a method:
4
10
  #
5
11
  # def search(criteria = {})
6
12
  # criteria.assert_valid_keys(:mass, :velocity, :time)
@@ -0,0 +1,23 @@
1
+ class Hash
2
+ # Returns a new hash with the results of running +block+ once for every value.
3
+ # The keys are unchanged.
4
+ #
5
+ # { a: 1, b: 2, c: 3 }.transform_values { |x| x * 2 }
6
+ # # => { a: 2, b: 4, c: 6 }
7
+ def transform_values
8
+ return enum_for(:transform_values) unless block_given?
9
+ result = self.class.new
10
+ each do |key, value|
11
+ result[key] = yield(value)
12
+ end
13
+ result
14
+ end unless method_defined? :transform_values
15
+
16
+ # Destructive +transform_values+
17
+ def transform_values!
18
+ return enum_for(:transform_values!) unless block_given?
19
+ each do |key, value|
20
+ self[key] = yield(value)
21
+ end
22
+ end unless method_defined? :transform_values!
23
+ end
@@ -1,8 +1,9 @@
1
+ require 'active_support/core_ext/hash/compact'
1
2
  require 'active_support/core_ext/hash/conversions'
2
3
  require 'active_support/core_ext/hash/deep_merge'
3
- require 'active_support/core_ext/hash/diff'
4
4
  require 'active_support/core_ext/hash/except'
5
5
  require 'active_support/core_ext/hash/indifferent_access'
6
6
  require 'active_support/core_ext/hash/keys'
7
7
  require 'active_support/core_ext/hash/reverse_merge'
8
8
  require 'active_support/core_ext/hash/slice'
9
+ require 'active_support/core_ext/hash/transform_values'
@@ -17,21 +17,6 @@ class Integer
17
17
  #
18
18
  # # equivalent to Time.now.advance(months: 4, years: 5)
19
19
  # (4.months + 5.years).from_now
20
- #
21
- # While these methods provide precise calculation when used as in the examples
22
- # above, care should be taken to note that this is not true if the result of
23
- # +months+, +years+, etc is converted before use:
24
- #
25
- # # equivalent to 30.days.to_i.from_now
26
- # 1.month.to_i.from_now
27
- #
28
- # # equivalent to 365.25.days.to_f.from_now
29
- # 1.year.to_f.from_now
30
- #
31
- # In such cases, Ruby's core
32
- # Date[http://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html] and
33
- # Time[http://ruby-doc.org/stdlib/libdoc/time/rdoc/Time.html] should be used for precision
34
- # date and time arithmetic.
35
20
  def months
36
21
  ActiveSupport::Duration.new(self * 30.days, [[:months, self]])
37
22
  end
@@ -0,0 +1,10 @@
1
+ require 'active_support/core_ext/module/concerning'
2
+
3
+ module Kernel
4
+ # A shortcut to define a toplevel concern, not within a module.
5
+ #
6
+ # See Module::Concerning for more.
7
+ def concern(topic, &module_definition)
8
+ Object.concern topic, &module_definition
9
+ end
10
+ end
@@ -3,7 +3,7 @@ module Kernel
3
3
  # Starts a debugging session if the +debugger+ gem has been loaded (call rails server --debugger to do load it).
4
4
  def debugger
5
5
  message = "\n***** Debugger requested, but was not available (ensure the debugger gem is listed in Gemfile/installed as gem): Start server with --debugger to enable *****\n"
6
- defined?(Rails) ? Rails.logger.info(message) : $stderr.puts(message)
6
+ defined?(Rails.logger) ? Rails.logger.info(message) : $stderr.puts(message)
7
7
  end
8
8
  alias breakpoint debugger unless respond_to?(:breakpoint)
9
9
  end
@@ -1,5 +1,6 @@
1
1
  require 'rbconfig'
2
2
  require 'tempfile'
3
+ require 'active_support/deprecation'
3
4
 
4
5
  module Kernel
5
6
  # Sets $VERBOSE to nil for the duration of the block and back to its original
@@ -31,9 +32,13 @@ module Kernel
31
32
 
32
33
  # For compatibility
33
34
  def silence_stderr #:nodoc:
35
+ ActiveSupport::Deprecation.warn(
36
+ "`#silence_stderr` is deprecated and will be removed in the next release."
37
+ ) #not thread-safe
34
38
  silence_stream(STDERR) { yield }
35
39
  end
36
40
 
41
+ # Deprecated : this method is not thread safe
37
42
  # Silences any stream for the duration of the block.
38
43
  #
39
44
  # silence_stream(STDOUT) do
@@ -63,8 +68,7 @@ module Kernel
63
68
  # puts 'This code gets executed and nothing related to ZeroDivisionError was seen'
64
69
  def suppress(*exception_classes)
65
70
  yield
66
- rescue Exception => e
67
- raise unless exception_classes.any? { |cls| e.kind_of?(cls) }
71
+ rescue *exception_classes
68
72
  end
69
73
 
70
74
  # Captures the given stream and returns it:
@@ -83,6 +87,9 @@ module Kernel
83
87
  # stream = capture(:stderr) { system('echo error 1>&2') }
84
88
  # stream # => "error\n"
85
89
  def capture(stream)
90
+ ActiveSupport::Deprecation.warn(
91
+ "`#capture(stream)` is deprecated and will be removed in the next release."
92
+ ) #not thread-safe
86
93
  stream = stream.to_s
87
94
  captured_stream = Tempfile.new(stream)
88
95
  stream_io = eval("$#{stream}")
@@ -94,6 +101,7 @@ module Kernel
94
101
  stream_io.rewind
95
102
  return captured_stream.read
96
103
  ensure
104
+ captured_stream.close
97
105
  captured_stream.unlink
98
106
  stream_io.reopen(origin_stream)
99
107
  end
@@ -105,6 +113,9 @@ module Kernel
105
113
  #
106
114
  # This method is not thread-safe.
107
115
  def quietly
116
+ ActiveSupport::Deprecation.warn(
117
+ "`#quietly` is deprecated and will be removed in the next release."
118
+ ) #not thread-safe
108
119
  silence_stream(STDOUT) do
109
120
  silence_stream(STDERR) do
110
121
  yield
@@ -1,4 +1,5 @@
1
- require 'active_support/core_ext/kernel/reporting'
2
1
  require 'active_support/core_ext/kernel/agnostics'
3
- require 'active_support/core_ext/kernel/debugger'
2
+ require 'active_support/core_ext/kernel/concern'
3
+ require 'active_support/core_ext/kernel/debugger' if RUBY_VERSION < '2.0.0'
4
+ require 'active_support/core_ext/kernel/reporting'
4
5
  require 'active_support/core_ext/kernel/singleton_class'
@@ -7,6 +7,7 @@ class LoadError
7
7
  ]
8
8
 
9
9
  unless method_defined?(:path)
10
+ # Returns the path which was unable to be loaded.
10
11
  def path
11
12
  @path ||= begin
12
13
  REGEXPS.find do |regex|
@@ -17,9 +18,11 @@ class LoadError
17
18
  end
18
19
  end
19
20
 
21
+ # Returns true if the given path name (except perhaps for the ".rb"
22
+ # extension) is the missing file which caused the exception to be raised.
20
23
  def is_missing?(location)
21
24
  location.sub(/\.rb$/, '') == path.sub(/\.rb$/, '')
22
25
  end
23
26
  end
24
27
 
25
- MissingSourceFile = LoadError
28
+ MissingSourceFile = LoadError
@@ -2,13 +2,16 @@ require 'active_support/core_ext/module/aliasing'
2
2
 
3
3
  module Marshal
4
4
  class << self
5
- def load_with_autoloading(source)
6
- load_without_autoloading(source)
5
+ def load_with_autoloading(source, proc = nil)
6
+ load_without_autoloading(source, proc)
7
7
  rescue ArgumentError, NameError => exc
8
- if exc.message.match(%r|undefined class/module (.+)|)
8
+ if exc.message.match(%r|undefined class/module (.+?)(::)?\z|)
9
9
  # try loading the class/module
10
- $1.constantize
11
- # if it is a IO we need to go back to read the object
10
+ loaded = $1.constantize
11
+
12
+ raise unless $1 == loaded.name
13
+
14
+ # if it is an IO we need to go back to read the object
12
15
  source.rewind if source.respond_to?(:rewind)
13
16
  retry
14
17
  else
@@ -19,9 +19,9 @@ class Module
19
19
  # alias_method :foo_without_feature?, :foo?
20
20
  # alias_method :foo?, :foo_with_feature?
21
21
  #
22
- # so you can safely chain foo, foo?, and foo! with the same feature.
22
+ # so you can safely chain foo, foo?, foo! and/or foo= with the same feature.
23
23
  def alias_method_chain(target, feature)
24
- # Strip out punctuation on predicates or bang methods since
24
+ # Strip out punctuation on predicates, bang or writer methods since
25
25
  # e.g. target?_without_feature is not a valid method name.
26
26
  aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
27
27
  yield(aliased_target, punctuation) if block_given?
@@ -27,7 +27,8 @@ class Module
27
27
 
28
28
  def attr_internal_define(attr_name, type)
29
29
  internal_name = attr_internal_ivar_name(attr_name).sub(/\A@/, '')
30
- class_eval do # class_eval is necessary on 1.9 or else the methods a made private
30
+ # class_eval is necessary on 1.9 or else the methods are made private
31
+ class_eval do
31
32
  # use native attr_* methods as they are faster on some Ruby implementations
32
33
  send("attr_#{type}", internal_name)
33
34
  end
@@ -1,10 +1,59 @@
1
1
  require 'active_support/core_ext/array/extract_options'
2
2
 
3
+ # Extends the module object with class/module and instance accessors for
4
+ # class/module attributes, just like the native attr* accessors for instance
5
+ # attributes.
3
6
  class Module
7
+ # Defines a class attribute and creates a class and instance reader methods.
8
+ # The underlying the class variable is set to +nil+, if it is not previously
9
+ # defined.
10
+ #
11
+ # module HairColors
12
+ # mattr_reader :hair_colors
13
+ # end
14
+ #
15
+ # HairColors.hair_colors # => nil
16
+ # HairColors.class_variable_set("@@hair_colors", [:brown, :black])
17
+ # HairColors.hair_colors # => [:brown, :black]
18
+ #
19
+ # The attribute name must be a valid method name in Ruby.
20
+ #
21
+ # module Foo
22
+ # mattr_reader :"1_Badname "
23
+ # end
24
+ # # => NameError: invalid attribute name
25
+ #
26
+ # If you want to opt out the creation on the instance reader method, pass
27
+ # <tt>instance_reader: false</tt> or <tt>instance_accessor: false</tt>.
28
+ #
29
+ # module HairColors
30
+ # mattr_writer :hair_colors, instance_reader: false
31
+ # end
32
+ #
33
+ # class Person
34
+ # include HairColors
35
+ # end
36
+ #
37
+ # Person.new.hair_colors # => NoMethodError
38
+ #
39
+ #
40
+ # Also, you can pass a block to set up the attribute with a default value.
41
+ #
42
+ # module HairColors
43
+ # cattr_reader :hair_colors do
44
+ # [:brown, :black, :blonde, :red]
45
+ # end
46
+ # end
47
+ #
48
+ # class Person
49
+ # include HairColors
50
+ # end
51
+ #
52
+ # Person.hair_colors # => [:brown, :black, :blonde, :red]
4
53
  def mattr_reader(*syms)
5
54
  options = syms.extract_options!
6
55
  syms.each do |sym|
7
- raise NameError.new('invalid attribute name') unless sym =~ /^[_A-Za-z]\w*$/
56
+ raise NameError.new("invalid attribute name: #{sym}") unless sym =~ /^[_A-Za-z]\w*$/
8
57
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
9
58
  @@#{sym} = nil unless defined? @@#{sym}
10
59
 
@@ -20,14 +69,60 @@ class Module
20
69
  end
21
70
  EOS
22
71
  end
72
+ class_variable_set("@@#{sym}", yield) if block_given?
23
73
  end
24
74
  end
75
+ alias :cattr_reader :mattr_reader
25
76
 
77
+ # Defines a class attribute and creates a class and instance writer methods to
78
+ # allow assignment to the attribute.
79
+ #
80
+ # module HairColors
81
+ # mattr_writer :hair_colors
82
+ # end
83
+ #
84
+ # class Person
85
+ # include HairColors
86
+ # end
87
+ #
88
+ # HairColors.hair_colors = [:brown, :black]
89
+ # Person.class_variable_get("@@hair_colors") # => [:brown, :black]
90
+ # Person.new.hair_colors = [:blonde, :red]
91
+ # HairColors.class_variable_get("@@hair_colors") # => [:blonde, :red]
92
+ #
93
+ # If you want to opt out the instance writer method, pass
94
+ # <tt>instance_writer: false</tt> or <tt>instance_accessor: false</tt>.
95
+ #
96
+ # module HairColors
97
+ # mattr_writer :hair_colors, instance_writer: false
98
+ # end
99
+ #
100
+ # class Person
101
+ # include HairColors
102
+ # end
103
+ #
104
+ # Person.new.hair_colors = [:blonde, :red] # => NoMethodError
105
+ #
106
+ # Also, you can pass a block to set up the attribute with a default value.
107
+ #
108
+ # class HairColors
109
+ # mattr_writer :hair_colors do
110
+ # [:brown, :black, :blonde, :red]
111
+ # end
112
+ # end
113
+ #
114
+ # class Person
115
+ # include HairColors
116
+ # end
117
+ #
118
+ # Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red]
26
119
  def mattr_writer(*syms)
27
120
  options = syms.extract_options!
28
121
  syms.each do |sym|
29
- raise NameError.new('invalid attribute name') unless sym =~ /^[_A-Za-z]\w*$/
122
+ raise NameError.new("invalid attribute name: #{sym}") unless sym =~ /^[_A-Za-z]\w*$/
30
123
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
124
+ @@#{sym} = nil unless defined? @@#{sym}
125
+
31
126
  def self.#{sym}=(obj)
32
127
  @@#{sym} = obj
33
128
  end
@@ -40,27 +135,78 @@ class Module
40
135
  end
41
136
  EOS
42
137
  end
138
+ send("#{sym}=", yield) if block_given?
43
139
  end
44
140
  end
141
+ alias :cattr_writer :mattr_writer
45
142
 
46
- # Extends the module object with module and instance accessors for class attributes,
47
- # just like the native attr* accessors for instance attributes.
143
+ # Defines both class and instance accessors for class attributes.
48
144
  #
49
- # module AppConfiguration
50
- # mattr_accessor :google_api_key
145
+ # module HairColors
146
+ # mattr_accessor :hair_colors
147
+ # end
51
148
  #
52
- # self.google_api_key = "123456789"
149
+ # class Person
150
+ # include HairColors
53
151
  # end
54
152
  #
55
- # AppConfiguration.google_api_key # => "123456789"
56
- # AppConfiguration.google_api_key = "overriding the api key!"
57
- # AppConfiguration.google_api_key # => "overriding the api key!"
153
+ # Person.hair_colors = [:brown, :black, :blonde, :red]
154
+ # Person.hair_colors # => [:brown, :black, :blonde, :red]
155
+ # Person.new.hair_colors # => [:brown, :black, :blonde, :red]
156
+ #
157
+ # If a subclass changes the value then that would also change the value for
158
+ # parent class. Similarly if parent class changes the value then that would
159
+ # change the value of subclasses too.
160
+ #
161
+ # class Male < Person
162
+ # end
163
+ #
164
+ # Male.hair_colors << :blue
165
+ # Person.hair_colors # => [:brown, :black, :blonde, :red, :blue]
58
166
  #
59
167
  # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
60
168
  # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
61
- # To opt out of both instance methods, pass <tt>instance_accessor: false</tt>.
62
- def mattr_accessor(*syms)
63
- mattr_reader(*syms)
64
- mattr_writer(*syms)
169
+ #
170
+ # module HairColors
171
+ # mattr_accessor :hair_colors, instance_writer: false, instance_reader: false
172
+ # end
173
+ #
174
+ # class Person
175
+ # include HairColors
176
+ # end
177
+ #
178
+ # Person.new.hair_colors = [:brown] # => NoMethodError
179
+ # Person.new.hair_colors # => NoMethodError
180
+ #
181
+ # Or pass <tt>instance_accessor: false</tt>, to opt out both instance methods.
182
+ #
183
+ # module HairColors
184
+ # mattr_accessor :hair_colors, instance_accessor: false
185
+ # end
186
+ #
187
+ # class Person
188
+ # include HairColors
189
+ # end
190
+ #
191
+ # Person.new.hair_colors = [:brown] # => NoMethodError
192
+ # Person.new.hair_colors # => NoMethodError
193
+ #
194
+ # Also you can pass a block to set up the attribute with a default value.
195
+ #
196
+ # module HairColors
197
+ # mattr_accessor :hair_colors do
198
+ # [:brown, :black, :blonde, :red]
199
+ # end
200
+ # end
201
+ #
202
+ # class Person
203
+ # include HairColors
204
+ # end
205
+ #
206
+ # Person.class_variable_get("@@hair_colors") #=> [:brown, :black, :blonde, :red]
207
+ def mattr_accessor(*syms, &blk)
208
+ mattr_reader(*syms, &blk)
209
+ mattr_writer(*syms, &blk)
65
210
  end
211
+ alias :cattr_accessor :mattr_accessor
66
212
  end