diff options
-rw-r--r-- | activesupport/CHANGELOG.md | 7 | ||||
-rw-r--r-- | activesupport/lib/active_support/duration.rb | 20 | ||||
-rw-r--r-- | activesupport/test/core_ext/duration_test.rb | 15 | ||||
-rw-r--r-- | guides/source/active_support_core_extensions.md | 15 |
4 files changed, 57 insertions, 0 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index f1dd7c312d..478fef2baf 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,3 +1,10 @@ +* Add `flatten` and `flatten!` methods to Duration objects. + + Example: + Date.today + (1.month + 1.month).flatten == Date.today + 2.months + + *Ionatan Wiznia* + * `require_dependency` accepts objects that respond to `to_path`, in particular `Pathname` instances. diff --git a/activesupport/lib/active_support/duration.rb b/activesupport/lib/active_support/duration.rb index 87b6407038..1db0ca51ae 100644 --- a/activesupport/lib/active_support/duration.rb +++ b/activesupport/lib/active_support/duration.rb @@ -81,6 +81,18 @@ module ActiveSupport to_i end + # Flattens all the +parts+ of the duration, and returns a + # new duration object. + def flatten + Duration.new(@value, flatten_parts) + end + + # Flattens all the +parts+ of this duration. + def flatten! + @parts = flatten_parts + self + end + protected def sum(sign, time = ::Time.current) #:nodoc: @@ -97,6 +109,14 @@ module ActiveSupport end end + def flatten_parts + @parts.inject({}) do |result, (name, value)| + result[name] ||= 0 + result[name] += value + result + end.to_a + end + private def method_missing(method, *args, &block) #:nodoc: diff --git a/activesupport/test/core_ext/duration_test.rb b/activesupport/test/core_ext/duration_test.rb index ed267cf4b9..cc24d7c74c 100644 --- a/activesupport/test/core_ext/duration_test.rb +++ b/activesupport/test/core_ext/duration_test.rb @@ -145,6 +145,21 @@ class DurationTest < ActiveSupport::TestCase assert_equal '172800', 2.days.to_json end + def test_flatten + a = 2.months + b = (1.month + 1.month).flatten + + assert_equal a.parts, b.parts + end + + def test_flatten! + a = (1.month + 1.month) + b = a.flatten + a.flatten! + + assert_equal a.parts, b.parts + end + protected def with_env_tz(new_tz = 'US/Eastern') old_tz, ENV['TZ'] = ENV['TZ'], new_tz diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md index d3f49b19fa..d11c17117e 100644 --- a/guides/source/active_support_core_extensions.md +++ b/guides/source/active_support_core_extensions.md @@ -3699,6 +3699,21 @@ Time.utc(1582, 10, 3) + 5.days # => Mon Oct 18 00:00:00 UTC 1582 ``` +When addinng or substracting durations, the resulting duration will be equivalent to subsequent calls to since or advance, so: + +```ruby +Date.new(2013,1,28) + 1.month + 1.month +# => Thu, 28 Mar 2013 +``` + +If you want to add durations and then use them as just one call to since or advance, you can use the flatten or flatten! method: + +```ruby +Date.new(2013,1,31) + (1.month + 1.month).flatten +# => Sun, 31 Mar 2013 +``` + + Extensions to `File` -------------------- |