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
@@ -0,0 +1,135 @@
1
+ require 'active_support/concern'
2
+
3
+ class Module
4
+ # = Bite-sized separation of concerns
5
+ #
6
+ # We often find ourselves with a medium-sized chunk of behavior that we'd
7
+ # like to extract, but only mix in to a single class.
8
+ #
9
+ # Extracting a plain old Ruby object to encapsulate it and collaborate or
10
+ # delegate to the original object is often a good choice, but when there's
11
+ # no additional state to encapsulate or we're making DSL-style declarations
12
+ # about the parent class, introducing new collaborators can obfuscate rather
13
+ # than simplify.
14
+ #
15
+ # The typical route is to just dump everything in a monolithic class, perhaps
16
+ # with a comment, as a least-bad alternative. Using modules in separate files
17
+ # means tedious sifting to get a big-picture view.
18
+ #
19
+ # = Dissatisfying ways to separate small concerns
20
+ #
21
+ # == Using comments:
22
+ #
23
+ # class Todo
24
+ # # Other todo implementation
25
+ # # ...
26
+ #
27
+ # ## Event tracking
28
+ # has_many :events
29
+ #
30
+ # before_create :track_creation
31
+ # after_destroy :track_deletion
32
+ #
33
+ # private
34
+ # def track_creation
35
+ # # ...
36
+ # end
37
+ # end
38
+ #
39
+ # == With an inline module:
40
+ #
41
+ # Noisy syntax.
42
+ #
43
+ # class Todo
44
+ # # Other todo implementation
45
+ # # ...
46
+ #
47
+ # module EventTracking
48
+ # extend ActiveSupport::Concern
49
+ #
50
+ # included do
51
+ # has_many :events
52
+ # before_create :track_creation
53
+ # after_destroy :track_deletion
54
+ # end
55
+ #
56
+ # private
57
+ # def track_creation
58
+ # # ...
59
+ # end
60
+ # end
61
+ # include EventTracking
62
+ # end
63
+ #
64
+ # == Mix-in noise exiled to its own file:
65
+ #
66
+ # Once our chunk of behavior starts pushing the scroll-to-understand it's
67
+ # boundary, we give in and move it to a separate file. At this size, the
68
+ # overhead feels in good proportion to the size of our extraction, despite
69
+ # diluting our at-a-glance sense of how things really work.
70
+ #
71
+ # class Todo
72
+ # # Other todo implementation
73
+ # # ...
74
+ #
75
+ # include TodoEventTracking
76
+ # end
77
+ #
78
+ # = Introducing Module#concerning
79
+ #
80
+ # By quieting the mix-in noise, we arrive at a natural, low-ceremony way to
81
+ # separate bite-sized concerns.
82
+ #
83
+ # class Todo
84
+ # # Other todo implementation
85
+ # # ...
86
+ #
87
+ # concerning :EventTracking do
88
+ # included do
89
+ # has_many :events
90
+ # before_create :track_creation
91
+ # after_destroy :track_deletion
92
+ # end
93
+ #
94
+ # private
95
+ # def track_creation
96
+ # # ...
97
+ # end
98
+ # end
99
+ # end
100
+ #
101
+ # Todo.ancestors
102
+ # # => Todo, Todo::EventTracking, Object
103
+ #
104
+ # This small step has some wonderful ripple effects. We can
105
+ # * grok the behavior of our class in one glance,
106
+ # * clean up monolithic junk-drawer classes by separating their concerns, and
107
+ # * stop leaning on protected/private for crude "this is internal stuff" modularity.
108
+ module Concerning
109
+ # Define a new concern and mix it in.
110
+ def concerning(topic, &block)
111
+ include concern(topic, &block)
112
+ end
113
+
114
+ # A low-cruft shortcut to define a concern.
115
+ #
116
+ # concern :EventTracking do
117
+ # ...
118
+ # end
119
+ #
120
+ # is equivalent to
121
+ #
122
+ # module EventTracking
123
+ # extend ActiveSupport::Concern
124
+ #
125
+ # ...
126
+ # end
127
+ def concern(topic, &module_definition)
128
+ const_set topic, Module.new {
129
+ extend ::ActiveSupport::Concern
130
+ module_eval(&module_definition)
131
+ }
132
+ end
133
+ end
134
+ include Concerning
135
+ end
@@ -1,7 +1,32 @@
1
+ require 'set'
2
+
1
3
  class Module
4
+ # Error generated by +delegate+ when a method is called on +nil+ and +allow_nil+
5
+ # option is not used.
6
+ class DelegationError < NoMethodError; end
7
+
8
+ RUBY_RESERVED_WORDS = Set.new(
9
+ %w(alias and BEGIN begin break case class def defined? do else elsif END
10
+ end ensure false for if in module next nil not or redo rescue retry
11
+ return self super then true undef unless until when while yield)
12
+ ).freeze
13
+
14
+ DELEGATION_RESERVED_KEYWORDS = Set.new(
15
+ %w(_ arg args block)
16
+ )
17
+
18
+ DELEGATION_RESERVED_METHOD_NAMES = Set.new(
19
+ RUBY_RESERVED_WORDS + DELEGATION_RESERVED_KEYWORDS
20
+ ).freeze
21
+
2
22
  # Provides a +delegate+ class method to easily expose contained objects'
3
23
  # public methods as your own.
4
24
  #
25
+ # ==== Options
26
+ # * <tt>:to</tt> - Specifies the target object
27
+ # * <tt>:prefix</tt> - Prefixes the new method with the target name or a custom prefix
28
+ # * <tt>:allow_nil</tt> - if set to true, prevents a +NoMethodError+ to be raised
29
+ #
5
30
  # The macro receives one or more method names (specified as symbols or
6
31
  # strings) and the name of the target object via the <tt>:to</tt> option
7
32
  # (also a symbol or string).
@@ -129,6 +154,8 @@ class Module
129
154
  #
130
155
  # Foo.new("Bar").name # raises NoMethodError: undefined method `name'
131
156
  #
157
+ # The target method must be public, otherwise it will raise +NoMethodError+.
158
+ #
132
159
  def delegate(*methods)
133
160
  options = methods.pop
134
161
  unless options.is_a?(Hash) && to = options[:to]
@@ -152,46 +179,47 @@ class Module
152
179
  line = line.to_i
153
180
 
154
181
  to = to.to_s
155
- to = 'self.class' if to == 'class'
182
+ to = "self.#{to}" if RUBY_RESERVED_WORDS.include?(to)
156
183
 
157
184
  methods.each do |method|
158
185
  # Attribute writer methods only accept one argument. Makes sure []=
159
186
  # methods still accept two arguments.
160
187
  definition = (method =~ /[^\]]=$/) ? 'arg' : '*args, &block'
161
188
 
162
- # The following generated methods call the target exactly once, storing
189
+ # The following generated method calls the target exactly once, storing
163
190
  # the returned value in a dummy variable.
164
191
  #
165
192
  # Reason is twofold: On one hand doing less calls is in general better.
166
193
  # On the other hand it could be that the target has side-effects,
167
- # whereas conceptualy, from the user point of view, the delegator should
194
+ # whereas conceptually, from the user point of view, the delegator should
168
195
  # be doing one call.
169
196
  if allow_nil
170
- module_eval(<<-EOS, file, line - 3)
171
- def #{method_prefix}#{method}(#{definition}) # def customer_name(*args, &block)
172
- _ = #{to} # _ = client
173
- if !_.nil? || nil.respond_to?(:#{method}) # if !_.nil? || nil.respond_to?(:name)
174
- _.#{method}(#{definition}) # _.name(*args, &block)
175
- end # end
176
- end # end
177
- EOS
197
+ method_def = [
198
+ "def #{method_prefix}#{method}(#{definition})",
199
+ "_ = #{to}",
200
+ "if !_.nil? || nil.respond_to?(:#{method})",
201
+ " _.#{method}(#{definition})",
202
+ "end",
203
+ "end"
204
+ ].join ';'
178
205
  else
179
- exception = %(raise "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
206
+ exception = %(raise DelegationError, "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
180
207
 
181
- module_eval(<<-EOS, file, line - 2)
182
- def #{method_prefix}#{method}(#{definition}) # def customer_name(*args, &block)
183
- _ = #{to} # _ = client
184
- _.#{method}(#{definition}) # _.name(*args, &block)
185
- rescue NoMethodError => e # rescue NoMethodError => e
186
- location = "%s:%d:in `%s'" % [__FILE__, __LINE__ - 2, '#{method_prefix}#{method}'] # location = "%s:%d:in `%s'" % [__FILE__, __LINE__ - 2, 'customer_name']
187
- if _.nil? && e.backtrace.first == location # if _.nil? && e.backtrace.first == location
188
- #{exception} # # add helpful message to the exception
189
- else # else
190
- raise # raise
191
- end # end
192
- end # end
193
- EOS
208
+ method_def = [
209
+ "def #{method_prefix}#{method}(#{definition})",
210
+ " _ = #{to}",
211
+ " _.#{method}(#{definition})",
212
+ "rescue NoMethodError => e",
213
+ " if _.nil? && e.name == :#{method}",
214
+ " #{exception}",
215
+ " else",
216
+ " raise",
217
+ " end",
218
+ "end"
219
+ ].join ';'
194
220
  end
221
+
222
+ module_eval(method_def, file, line)
195
223
  end
196
224
  end
197
225
  end
@@ -1,5 +1,3 @@
1
- require 'active_support/deprecation/method_wrappers'
2
-
3
1
  class Module
4
2
  # deprecate :foo
5
3
  # deprecate bar: 'message'
@@ -59,20 +59,4 @@ class Module
59
59
  def local_constants #:nodoc:
60
60
  constants(false)
61
61
  end
62
-
63
- # *DEPRECATED*: Use +local_constants+ instead.
64
- #
65
- # Returns the names of the constants defined locally as strings.
66
- #
67
- # module M
68
- # X = 1
69
- # end
70
- # M.local_constant_names # => ["X"]
71
- #
72
- # This method is useful for forward compatibility, since Ruby 1.8 returns
73
- # constant names as strings, whereas 1.9 returns them as symbols.
74
- def local_constant_names
75
- ActiveSupport::Deprecation.warn 'Module#local_constant_names is deprecated, use Module#local_constants instead'
76
- local_constants.map { |c| c.to_s }
77
- end
78
62
  end
@@ -0,0 +1,13 @@
1
+ class Module
2
+ ###
3
+ # TODO: remove this after 1.9 support is dropped
4
+ def methods_transplantable? # :nodoc:
5
+ x = Module.new {
6
+ def foo; end # :nodoc:
7
+ }
8
+ Module.new { define_method :bar, x.instance_method(:foo) }
9
+ true
10
+ rescue TypeError
11
+ false
12
+ end
13
+ end
@@ -4,6 +4,7 @@ require 'active_support/core_ext/module/anonymous'
4
4
  require 'active_support/core_ext/module/reachable'
5
5
  require 'active_support/core_ext/module/attribute_accessors'
6
6
  require 'active_support/core_ext/module/attr_internal'
7
+ require 'active_support/core_ext/module/concerning'
7
8
  require 'active_support/core_ext/module/delegation'
8
9
  require 'active_support/core_ext/module/deprecation'
9
10
  require 'active_support/core_ext/module/remove_method'
@@ -41,7 +41,7 @@ class Numeric
41
41
  # 1000.to_s(:percentage, delimiter: '.', separator: ',') # => 1.000,000%
42
42
  # 302.24398923423.to_s(:percentage, precision: 5) # => 302.24399%
43
43
  # 1000.to_s(:percentage, locale: :fr) # => 1 000,000%
44
- # 100.to_s(:percentage, format: '%n %') # => 100 %
44
+ # 100.to_s(:percentage, format: '%n %') # => 100.000 %
45
45
  #
46
46
  # Delimited:
47
47
  # 12345678.to_s(:delimited) # => 12,345,678
@@ -78,7 +78,7 @@ class Numeric
78
78
  # 1234567.to_s(:human_size, precision: 2) # => 1.2 MB
79
79
  # 483989.to_s(:human_size, precision: 2) # => 470 KB
80
80
  # 1234567.to_s(:human_size, precision: 2, separator: ',') # => 1,2 MB
81
- # 1234567890123.to_s(:human_size, precision: 5) # => "1.1229 TB"
81
+ # 1234567890123.to_s(:human_size, precision: 5) # => "1.1228 TB"
82
82
  # 524288000.to_s(:human_size, precision: 5) # => "500 MB"
83
83
  #
84
84
  # Human-friendly format:
@@ -118,7 +118,15 @@ class Numeric
118
118
  end
119
119
  end
120
120
 
121
- [Float, Fixnum, Bignum, BigDecimal].each do |klass|
121
+ klasses = [Float, BigDecimal]
122
+ # Ruby 2.4+ unifies Fixnum & Bignum into Integer.
123
+ if 0.class == Integer
124
+ klasses << Integer
125
+ else
126
+ klasses << Fixnum << Bignum
127
+ end
128
+
129
+ klasses.each do |klass|
122
130
  klass.send(:alias_method, :to_default_s, :to_s)
123
131
 
124
132
  klass.send(:define_method, :to_s) do |*args|
@@ -16,21 +16,6 @@ class Numeric
16
16
  #
17
17
  # # equivalent to Time.current.advance(months: 4, years: 5)
18
18
  # (4.months + 5.years).from_now
19
- #
20
- # While these methods provide precise calculation when used as in the examples above, care
21
- # should be taken to note that this is not true if the result of `months', `years', etc is
22
- # converted before use:
23
- #
24
- # # equivalent to 30.days.to_i.from_now
25
- # 1.month.to_i.from_now
26
- #
27
- # # equivalent to 365.25.days.to_f.from_now
28
- # 1.year.to_f.from_now
29
- #
30
- # In such cases, Ruby's core
31
- # Date[http://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html] and
32
- # Time[http://ruby-doc.org/stdlib/libdoc/time/rdoc/Time.html] should be used for precision
33
- # date and time arithmetic.
34
19
  def seconds
35
20
  ActiveSupport::Duration.new(self, [[:seconds, self]])
36
21
  end
@@ -61,19 +46,9 @@ class Numeric
61
46
  end
62
47
  alias :fortnight :fortnights
63
48
 
64
- # Reads best without arguments: 10.minutes.ago
65
- def ago(time = ::Time.current)
66
- time - self
49
+ # Used with the standard time durations, like 1.hour.in_milliseconds --
50
+ # so we can feed them to JavaScript functions like getTime().
51
+ def in_milliseconds
52
+ self * 1000
67
53
  end
68
-
69
- # Reads best with argument: 10.minutes.until(time)
70
- alias :until :ago
71
-
72
- # Reads best with argument: 10.minutes.since(time)
73
- def since(time = ::Time.current)
74
- time + self
75
- end
76
-
77
- # Reads best without arguments: 10.minutes.from_now
78
- alias :from_now :since
79
54
  end
@@ -2,38 +2,44 @@
2
2
 
3
3
  class Object
4
4
  # An object is blank if it's false, empty, or a whitespace string.
5
- # For example, '', ' ', +nil+, [], and {} are all blank.
5
+ # For example, +false+, '', ' ', +nil+, [], and {} are all blank.
6
6
  #
7
- # This simplifies:
7
+ # This simplifies
8
8
  #
9
- # if address.nil? || address.empty?
9
+ # !address || address.empty?
10
10
  #
11
- # ...to:
11
+ # to
12
12
  #
13
- # if address.blank?
13
+ # address.blank?
14
+ #
15
+ # @return [true, false]
14
16
  def blank?
15
- respond_to?(:empty?) ? empty? : !self
17
+ respond_to?(:empty?) ? !!empty? : !self
16
18
  end
17
19
 
18
- # An object is present if it's not <tt>blank?</tt>.
20
+ # An object is present if it's not blank.
21
+ #
22
+ # @return [true, false]
19
23
  def present?
20
24
  !blank?
21
25
  end
22
26
 
23
- # Returns object if it's <tt>present?</tt> otherwise returns +nil+.
24
- # <tt>object.presence</tt> is equivalent to <tt>object.present? ? object : nil</tt>.
27
+ # Returns the receiver if it's present otherwise returns +nil+.
28
+ # <tt>object.presence</tt> is equivalent to
25
29
  #
26
- # This is handy for any representation of objects where blank is the same
27
- # as not present at all. For example, this simplifies a common check for
28
- # HTTP POST/query parameters:
30
+ # object.present? ? object : nil
31
+ #
32
+ # For example, something like
29
33
  #
30
34
  # state = params[:state] if params[:state].present?
31
35
  # country = params[:country] if params[:country].present?
32
36
  # region = state || country || 'US'
33
37
  #
34
- # ...becomes:
38
+ # becomes
35
39
  #
36
40
  # region = params[:state].presence || params[:country].presence || 'US'
41
+ #
42
+ # @return [Object]
37
43
  def presence
38
44
  self if present?
39
45
  end
@@ -43,6 +49,8 @@ class NilClass
43
49
  # +nil+ is blank:
44
50
  #
45
51
  # nil.blank? # => true
52
+ #
53
+ # @return [true]
46
54
  def blank?
47
55
  true
48
56
  end
@@ -52,6 +60,8 @@ class FalseClass
52
60
  # +false+ is blank:
53
61
  #
54
62
  # false.blank? # => true
63
+ #
64
+ # @return [true]
55
65
  def blank?
56
66
  true
57
67
  end
@@ -61,6 +71,8 @@ class TrueClass
61
71
  # +true+ is not blank:
62
72
  #
63
73
  # true.blank? # => false
74
+ #
75
+ # @return [false]
64
76
  def blank?
65
77
  false
66
78
  end
@@ -71,6 +83,8 @@ class Array
71
83
  #
72
84
  # [].blank? # => true
73
85
  # [1,2,3].blank? # => false
86
+ #
87
+ # @return [true, false]
74
88
  alias_method :blank?, :empty?
75
89
  end
76
90
 
@@ -79,18 +93,28 @@ class Hash
79
93
  #
80
94
  # {}.blank? # => true
81
95
  # { key: 'value' }.blank? # => false
96
+ #
97
+ # @return [true, false]
82
98
  alias_method :blank?, :empty?
83
99
  end
84
100
 
85
101
  class String
102
+ BLANK_RE = /\A[[:space:]]*\z/
103
+
86
104
  # A string is blank if it's empty or contains whitespaces only:
87
105
  #
88
- # ''.blank? # => true
89
- # ' '.blank? # => true
90
- # ' '.blank? # => true
91
- # ' something here '.blank? # => false
106
+ # ''.blank? # => true
107
+ # ' '.blank? # => true
108
+ # "\t\n\r".blank? # => true
109
+ # ' blah '.blank? # => false
110
+ #
111
+ # Unicode whitespace is supported:
112
+ #
113
+ # "\u00a0".blank? # => true
114
+ #
115
+ # @return [true, false]
92
116
  def blank?
93
- self !~ /[^[:space:]]/
117
+ BLANK_RE === self
94
118
  end
95
119
  end
96
120
 
@@ -99,6 +123,8 @@ class Numeric #:nodoc:
99
123
  #
100
124
  # 1.blank? # => false
101
125
  # 0.blank? # => false
126
+ #
127
+ # @return [false]
102
128
  def blank?
103
129
  false
104
130
  end
@@ -8,8 +8,8 @@ class Object
8
8
  # dup = object.deep_dup
9
9
  # dup.instance_variable_set(:@a, 1)
10
10
  #
11
- # object.instance_variable_defined?(:@a) #=> false
12
- # dup.instance_variable_defined?(:@a) #=> true
11
+ # object.instance_variable_defined?(:@a) # => false
12
+ # dup.instance_variable_defined?(:@a) # => true
13
13
  def deep_dup
14
14
  duplicable? ? dup : self
15
15
  end
@@ -22,8 +22,8 @@ class Array
22
22
  # dup = array.deep_dup
23
23
  # dup[1][2] = 4
24
24
  #
25
- # array[1][2] #=> nil
26
- # dup[1][2] #=> 4
25
+ # array[1][2] # => nil
26
+ # dup[1][2] # => 4
27
27
  def deep_dup
28
28
  map { |it| it.deep_dup }
29
29
  end
@@ -36,8 +36,8 @@ class Hash
36
36
  # dup = hash.deep_dup
37
37
  # dup[:a][:c] = 'c'
38
38
  #
39
- # hash[:a][:c] #=> nil
40
- # dup[:a][:c] #=> "c"
39
+ # hash[:a][:c] # => nil
40
+ # dup[:a][:c] # => "c"
41
41
  def deep_dup
42
42
  each_with_object(dup) do |(key, value), hash|
43
43
  hash[key.deep_dup] = value.deep_dup