Commit Graph

5698 Commits

Author SHA1 Message Date
Andrew White
8931916f4a Ensure duration parsing is consistent across DST changes
Previously `ActiveSupport::Duration.parse` used `Time.current` and
`Time#advance` to calculate the number of seconds in the duration
from an arbitrary collection of parts. However as `advance` tries to
be consistent across DST boundaries this meant that either the
duration was shorter or longer depending on the time of year.

This was fixed by using an absolute reference point in UTC which
isn't subject to DST transitions. An arbitrary date of Jan 1st, 2000
was chosen for no other reason that it seemed appropriate.

Additionally, duration parsing should now be marginally faster as we
are no longer creating instances of `ActiveSupport::TimeWithZone`
every time we parse a duration string.

Fixes #26941.
2016-10-31 17:25:43 +00:00
Prathamesh Sonpatki
8776f15b44
Fix an issue with JSON encoding of "Infinity" and "NaN" values
- When `as_json` returns `Infinity` or `NaN` as the value of any of the key,
  we don't used to call `as_json` on it as it was treated as primitive.
- This used to pass `Infinity` or `NaN` to `JSON.generate` and Ruby used
  to throw an error for `Infinity/NaN not allowed in JSON.`
- This patch changes the code to call `as_json` on these primitives so
  that they are converted to proper values before being passed to
  `JSON.generate`.
- Fixes #26877.
2016-10-30 20:08:55 +05:30
Rafael Mendonça França
fe1f4b2ad5
Add more rubocop rules about whitespaces 2016-10-29 01:17:49 -02:00
Xavier Noria
56832e791f let Regexp#match? be globally available
Regexp#match? should be considered to be part of the Ruby core library. We are
emulating it for < 2.4, but not having to require the extension is part of the
illusion of the emulation.
2016-10-27 09:13:55 +02:00
bogdanvlviv
5faa9a235c Add missing + around a some literals.
Mainly around `nil`

[ci skip]
2016-10-27 00:27:47 +03:00
yui-knk
c51a9b975f Ensure #transform_values of HWIDA to return HWIDA
On Ruby 2.4, naitive `Hash#transform_values` is implemented.
`Hash#transform_values` uses an instance of Hash (`rb_hash_new`) to
collect returned values of a block.
For ensuring `#transform_values` of HWIDA to return HWIDA, we should
define `#transform_values` on HWIDA.
2016-10-26 11:18:10 +09:00
Rafael Mendonça França
c5d46a8a4e
Whitespace 2016-10-25 14:54:25 -02:00
Rafael França
3cc30db12c Merge pull request #26868 from prathamesh-sonpatki/use-hash-compact-from-ruby-24
Use Hash#compact and Hash#compact! from Ruby 2.4
2016-10-24 23:56:09 -02:00
Guo Xiang Tan
308e84e982 Broadcast#silence breaks custom loggers that does not include LoggerSilence. 2016-10-24 18:26:13 +08:00
Prathamesh Sonpatki
69a3fa1efc
Use Hash#compact and Hash#compact! from Ruby 2.4
- Ruby 2.4 has added Hash#compact and Hash#compact! so we can use it
  now.
- Reference: https://bugs.ruby-lang.org/issues/11818 and https://bugs.ruby-lang.org/issues/12863.
2016-10-23 20:54:39 +05:30
claudiob
fbda46758b Revert #26826 and add documentation
This reverts commit a01cf703 as explained in the comment to #26826:

Realized that this PR caused the following warning in Travis CI:

```
/home/travis/build/rails/rails/activesupport/lib/active_support/dependencies.rb:293: warning: loading in progress, circular require considered harmful - /home/travis/build/rails/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb
```

Indeed, `active_support/core_ext/hash/indifferent_access.rb` **needs** to require `active_support/hash_with_indifferent_access.rb` in order to access the class `ActiveSupport::HashWithIndifferentAccess`.

The other way around, though, is not _strictly_ required, unless someone tries (like I did in the [gist above](https://gist.github.com/claudiob/43cc7fe77ff95951538af2825a71e5ec)) to use `ActiveSupport::HashWithIndifferentAccess` by only requiring `active_support/hash_with_indifferent_access.rb` without first requiring `active_support/core_ext/hash/indifferent_access.rb`.

I think the solution to this is to revert this PR and instead change the documentation to explicitly state that **developers should not require 'active_support/hash_with_indifferent_access'** if all they want is to use `ActiveSupport::HashWithIndifferentAccess` – instead they should require `active_support/core_ext/hash/indifferent_access.rb`.
2016-10-21 22:55:51 -07:00
Rafael França
7bbd3e68ed Merge pull request #26843 from denisovlev/strptime_timestamps
Fix `ActiveSupport::TimeZone#strptime` cannot parse timestamps (%Q, %s)
2016-10-22 00:12:47 -03:00
Claudio B
397025db76 Merge pull request #26826 from claudiob/add-require
Add missing require in active_support/hash_with_indifferent_access.rb
2016-10-21 18:08:34 -07:00
Aaron Patterson
b6f935bbf9
Use on_load to trigger commandline processing code
We need to use on_load so that plugins will get the same functionality
2016-10-21 14:44:17 -07:00
Charles Oliver Nutter
2674392058 Additional fix for argument-splat ordering differences.
See #26854
2016-10-21 10:16:58 -05:00
Charles Oliver Nutter
5f382d41c3 Explicitly unpack the expanded args to avoid execution order diff.
In https://bugs.ruby-lang.org/issues/12860 I argue that MRI's
execution order here is incorrect. The splatting of the 'c' args
should happen before the shift, but it happens after. On JRuby, it
behaves the way you would expect, leading to the 'c' args splat
still containing the block and producing an error like "cannot
convert proc to symbol" when the send attempts to coerce
it.

This patch makes the unpacking order explicit with a multi-assign,
which behaves properly on all implementations I tested.
2016-10-21 09:33:25 -05:00
denisovlev
07ffe7a621 Fix ActiveSupport::TimeZone#strptime cannot parse timestamps (%Q, %s) 2016-10-21 13:19:08 +03:00
Andrew White
f2c6db41ba Merge pull request #26839 from renuo/fix-missing-nsec-transfer
Fix copy_time_to: Copy nsec instead of usec
2016-10-21 07:03:32 +01:00
Yves Senn
dce4751a74 doc, hide non-public methods form the api docs. [ci skip]
This is a follow up to #25681, specifically this comment:
https://github.com/rails/rails/pull/25681#issuecomment-238294002

The way the thread local variable is stored is an implementation detail
and subject to change. It makes no sense to only generate a reader or
writer as you'd have to know where to read from or where it writes to.
2016-10-20 21:21:55 +02:00
Josua Schmid
fc72d6815a
Fix copy_time_to: Copy nsec instead of usec
`copy_time_to` is a helper function for date and time calculations.
It's being used by `prev_week`, `next_week` and `prev_weekday` to keep
the time fraction when jumping around between days.

Previously the nanoseconds part was lost during the operation. This
lead to problems in practice if you were using the `end_of_day`
calculation. Resulting in the time fraction of `end_of_day` not being
the same as next week's `end_of_day`.

With this fix `copy_time_to` doesn't forget the `nsec` digits.
2016-10-20 10:49:59 +02:00
claudiob
a01cf703e2 Add missing require 2016-10-19 11:48:43 -07:00
Rafael Mendonça França
bd8b50d2e5
Add comment to remove code when we are in Ruby 2.4 2016-10-14 23:57:03 -03:00
Jesús Burgos
e84ed4fd17 Use built-in #transform_values when available.
The methods Hash#transform_values and Hash#transform_values! have been
implemented in Ruby and they'll be available as part of the standard
library.

Here's the link to the discussion in Ruby's issue tracker:
https://bugs.ruby-lang.org/issues/12512

These methods are implemented in C so they're expected to perform
better.
2016-10-14 14:27:27 +02:00
Rafael França
3c8f26ac14 Merge pull request #26531 from y-yagi/remove_unused_benchmark
remove unused require `benchmark`
2016-10-10 22:04:00 -03:00
Matthew Draper
cb0452e9a5 Fixnum and Bignum are deprecated in Ruby trunk
https://bugs.ruby-lang.org/issues/12739
2016-10-08 08:13:11 +10:30
Matthew Draper
0464b728e2 Merge pull request #26359 from maclover7/jm-speed-up-time
Speed up Time.zone.now
2016-10-06 02:35:35 +10:30
Matthew Draper
4d6feef792 Merge pull request #26684 from matthewd/executor-serial
Avoid bumping the class serial when invoking executor
2016-10-05 05:23:48 +10:30
Matthew Draper
6ecb14715e Merge pull request #26686 from matthewd/deprecation-caller
Correct caller tracking in delegated deprecation methods
2016-10-05 05:23:20 +10:30
Matthew Draper
e8b36e7711 Avoid bumping the class serial when invoking executor 2016-10-03 13:35:51 +10:30
Jon Moss
353122c9da Speed up Time.zone.now
@amatsuda, during his RailsConf talk this past year, presented a
benchmark that showed `Time.zone.now` (an Active Support joint)
performing 24.97x slower than Ruby's `Time.now`. Rails master appears to
be a _bit_ faster than that, currently clocking in at 18.25x slower than
`Time.now`. Here's the exact benchmark data for that:

```
Warming up --------------------------------------
            Time.now   127.923k i/100ms
       Time.zone.now    10.275k i/100ms
Calculating -------------------------------------
            Time.now      1.946M (± 5.9%) i/s -      9.722M in   5.010236s
       Time.zone.now    106.625k (± 4.3%) i/s -    534.300k in   5.020343s

Comparison:
            Time.now:  1946220.1 i/s
       Time.zone.now:   106625.5 i/s - 18.25x slower
```

What if I told you we could make `Time.zone.now` _even_ faster? Well,
that's exactly what this patch accomplishes. When creating `ActiveSupport::TimeWithZone`
objects, we try to convert the provided time to be in a UTC format. All
this patch does is, in the method where we convert a provided time to
UTC, check if the provided time is already UTC, and is a `Time` object
and then return early if that is the case, This sidesteps having to continue on,
and create a new `Time` object from scratch. Here's the exact benchmark
data for my patch:

```
Warming up --------------------------------------
            Time.now   124.136k i/100ms
       Time.zone.now    26.260k i/100ms
Calculating -------------------------------------
            Time.now      1.894M (± 6.4%) i/s -      9.434M in   5.000153s
       Time.zone.now    301.654k (± 4.3%) i/s -      1.523M in   5.058328s

Comparison:
            Time.now:  1893958.0 i/s
       Time.zone.now:   301653.7 i/s - 6.28x slower
```

With this patch, we go from `Time.zone.now` being 18.25x slower than
`Time.now` to only being 6.28x slower than `Time.now`. I'd obviously love some
verification on this patch, since these numbers sound pretty interesting... :)

This is the benchmark-ips report I have been using while working on this:

```ruby
require 'benchmark/ips'

Time.zone = 'Eastern Time (US & Canada)'

Benchmark.ips do |x|
  x.report('Time.now') {
    Time.now
  }

  x.report('Time.zone.now') {
    Time.zone.now
  }

  x.compare!
end
```

cc @amatsuda
cc performance folks @tenderlove and @schneems

![Pretty... pretty... pretty good.](https://media.giphy.com/media/bWeR8tA1QV4cM/giphy.gif)
2016-10-02 15:12:46 -04:00
Matthew Draper
62ed56135b Correct caller tracking in delegated deprecation methods 2016-10-03 05:22:28 +10:30
Andrew White
9128ba5cd4 Cache to_time to improve performance when comparing
In #25880 we tried to cache localtime to fix the performance
regression but that proved to be difficult due to the fact that
localtime/getlocal can take a utc_offset argument. We tried
caching based on the argument but since the argument can be nil
sometimes that meant that if the TZ environment variable changed
then the cached value for nil became invalid. By moving the
caching to DateAndTime#compatibility we don't have to worry about
arguments since it doesn't take any.

There is a possible edge condition where preserve_timezone is set
to false and the system timezone changes then it could result in
a cached value being incorrect but the only way to fix this would
be to remove all caching and live with the performance issue.
2016-10-02 17:15:44 +01:00
Andrew White
bd8f0871c2 Revert "Merge pull request #25880 from ryandv/fix_performance_regression_in_timewithzone_to_time"
Turns out trying to cache on localtime with arguments is too hard
so we'll do it on DateAndTime::Compatibility#to_time instead.

This reverts commit 3132fa6b7d9585e04eb44b25b55d298391b040b5, reversing
changes made to 6949f8e5e7dc901d4e04ebab6c975afb33ca44c9.
2016-10-02 17:02:27 +01:00
Andrew White
6c1dac00df Revert "Merge pull request #26677 from tbalthazar/26644"
Turns out trying to cache on localtime with arguments is too hard
so we'll do it on DateAndTime::Compatibility#to_time instead.

This reverts commit 9ce2d1b1a43fc4ef3db59849b7412d30583a4074, reversing
changes made to 53ede1aff2025d4391d0e05ba471fdaf3110a99c.
2016-10-02 17:00:18 +01:00
Andrew White
9ce2d1b1a4 Merge pull request #26677 from tbalthazar/26644
Fix `ActiveSupport::TimeWithZone#localtime`
2016-10-01 21:30:02 +01:00
Thomas Balthazar
607a6c7a9a Fix ActiveSupport::TimeWithZone#localtime
Previously memoization in `localtime` wasn't taking the `utc_offset`
parameter into account when returning a cached value. It now caches the
computed value depending on the `utc_offset` parameter, e.g:

    Time.zone = "US/Eastern"

    t = Time.zone.local(2016,5,2,11)
    # => Mon, 02 May 2016 11:00:00 EDT -04:00

    t.localtime(-7200)
    # => 2016-05-02 13:00:00 -0200

    t.localtime(-3600)
    # => 2016-05-02 14:00:00 -0100
2016-10-01 13:38:43 +02:00
Matthew Draper
871ca21f6a Tighten the backtrace pollution from passing through callbacks
Callbacks are everywhere, so it's better if we can avoid making a mess
of the backtrace just because we've passed through a callback hook.

I'm making no effort to the before/after invocations: those only affect
backtraces while they're running. The calls that matter are the ones
that remain on the call stack after run_callbacks yields: around
callbacks, and internal book-keeping around the before/afters.
2016-09-30 06:57:43 +09:30
Akira Matsuda
b18f8b9d77 Merge pull request #26402 from mtsmfm/remove-dead-constants
Remove dead constants
2016-09-29 18:52:39 +09:00
Jon Moss
c93b80d53d Merge pull request #26654 from Neodelf/activesupport_1
[ci skip] Remove not necessary whitespace
2016-09-28 17:02:22 -04:00
Andrey Molchanov
1ba3ee4dd1 [ci skip] Use class name instead of path to file 2016-09-28 23:31:54 +03:00
Andrey Molchanov
05eb2c0835 [ci skip] Remove not necessary whitespace 2016-09-28 23:24:26 +03:00
yuuji.yaginuma
34a313aa35 fix typo in DateAndTime::Calculations#all_week doc [ci skip]
`Date.week_start` does not exist. `Date.beginning_of_week` seems to be correct.
Ref: #5339
2016-09-27 12:23:52 +09:00
Kasper Timm Hansen
0dfc467587 fffffff, Add code missing in 29f0fbd 2016-09-25 20:38:12 +02:00
Kasper Timm Hansen
29f0fbd5db Revise setting of run_with_rails_extension.
The Rails test runner supports three ways to run tests: directly, via rake, or ruby.

When Running with Ruby ala `ruby -Itest test/models/post_test.rb` our test file would
be evaluated first, requiring `test_helper` and then `active_support/testing/autorun`
that would then require the test file (which it hadn't been before) thus reevaluating
it. This caused exceptions if using Active Support's declarative syntax.

Fix this by shifting around when we set the how we're run to closer mimick the require
order.

If we're running with `bin/rails test` the test command file is run first and we then
set `run_with_rails_extension`, later we hit `active_support/testing/autorun` and do
nothing — because we've been run elsewhere.

If we at this point haven't set `run_with_rails_extension` we've been running with
`ruby` this whole time and thus we set that.

We should always trigger `Minitest.autorun` as it doesn't hurt to call it twice.

Consolidate the two methods into a single one that better brings out the intent of
why they're there.
2016-09-25 20:36:30 +02:00
Thomas Balthazar
76c2553b88 Fix ActiveSupport::TimeWithZone#in
Previously calls to `in` were being sent to the non-DST aware
method `Time#since` via `method_missing`. It is now aliased to
the DST aware `ActiveSupport::TimeWithZone#+` which handles
transitions across DST boundaries, e.g:

    Time.zone = "US/Eastern"

    t = Time.zone.local(2016,11,6,1)
    # => Sun, 06 Nov 2016 01:00:00 EDT -05:00

    t.in(1.hour)
    # => Sun, 06 Nov 2016 01:00:00 EST -05:00
2016-09-24 09:39:51 +02:00
Aaron Patterson
0bc196518a Merge pull request #26563 from knugie/fix_issue_26430
Prevent circular require of proxy_wrappers.rb, Fixes #26430
2016-09-23 11:27:04 -07:00
Vipul A M
3b0da83c81 Merge pull request #26594 from y-yagi/fix_formatting_of_define_callbacks
fix formatting of `define_callbacks` doc [ci skip]
2016-09-23 15:10:46 +05:30
yuuji.yaginuma
508edbc04f fix formatting of define_callbacks doc [ci skip]
Single backticks don't work with rdoc.
2016-09-23 18:37:45 +09:00
Richard Schneeman
bf19c2230d Merge pull request #26524 from y-yagi/add_check_of_argument
add check of argument
2016-09-22 09:29:25 -05:00
Wolfgang Teuber
b355a43f0e Prevent circular require of proxy_wrappers.rb, Fixes #26430 2016-09-21 00:40:48 +02:00
yuuji.yaginuma
fa5200fc21 change MemCacheStore#increment and MemCacheStore#decrement to public API [ci skip]
I'm not sure why these methods not public. But these methods are public in
other cache stores, I think that may be in public.

Ref:
http://edgeapi.rubyonrails.org/classes/ActiveSupport/Cache/Store.html#method-i-increment
http://edgeapi.rubyonrails.org/classes/ActiveSupport/Cache/FileStore.html#method-i-increment
http://edgeapi.rubyonrails.org/classes/ActiveSupport/Cache/MemoryStore.html#method-i-increment
http://edgeapi.rubyonrails.org/classes/ActiveSupport/Cache/NullStore.html#method-i-increment
2016-09-18 11:07:11 +09:00
Andrey Molchanov
e1252e073a [ci skip] Fixed commas according to Oxford comma in rdoc and guides 2016-09-17 22:36:13 +03:00
yuuji.yaginuma
77b2e46df4 remove unused require benchmark
`Benchmark` was removed at 4215e9a
2016-09-17 20:15:28 +09:00
yuuji.yaginuma
97544ed177 add check of argument
`#fetch_multi` in case did not cache hit, to write a cache using the block value.
https://github.com/rails/rails/blob/master/activesupport/lib/active_support/cache.rb#L383..L384

Therefore, block is a need to pass always, I think should check first.
2016-09-17 16:34:38 +09:00
yuuji.yaginuma
5de91258be fix formatting of Cache::Store#fetch [ci skip]
Single backticks don't work with rdoc.
2016-09-17 15:18:06 +09:00
Tomer Brisker
9e5741ca75 Reword according to feedback 2016-09-15 15:36:27 +03:00
Ryuta Kamizono
3464cd5c28 Fix broken comments indentation caused by rubocop auto-correct [ci skip]
All indentation was normalized by rubocop auto-correct at 80e66cc4d90bf8c15d1a5f6e3152e90147f00772.
But comments was still kept absolute position. This commit aligns
comments with method definitions for consistency.
2016-09-14 18:26:32 +09:00
Tomer Brisker
2f3637d3cd Clarify that mattr_* creates public methods 2016-09-13 16:09:29 +03:00
Ryunosuke Sato
b9e98d62c2 Remove the word "mongrel" from documents
Currently mongrel is not maintained.
And it couldn't be built with any Ruby versions that
supported by Rails.

It is reasonable to remove the word "mongrel" in order to avoid
confusion from newcomer.
2016-09-07 01:59:37 +09:00
Alex Kitchens
fbccae4d19 Fix Remaining Case-In-Assignment Statement Formatting
Recently, the Rails team made an effort to keep the source code consistent, using Ruboco
(bb1ecdcc677bf6e68e0252505509c089619b5b90 and below). Some of the case
statements were missed.

This changes the case statements' formatting and is consistent with changes
in 810dff7c9fa9b2a38eb1560ce0378d760529ee6b and db63406cb007ab3756d2a96d2e0b5d4e777f8231.
2016-09-06 09:34:09 -05:00
Fumiaki MATSUSHIMA
293cdecee3 Remove dead constants
It seems that we forgot to remove some codes on 7ab4775106
2016-09-06 21:58:34 +09:00
yuuji.yaginuma
951353e476 change Class#descendants to public API [ci skip]
`Class#descendants` has already been displayed in Rails guide,
so I think that may be displayed in doc.
http://guides.rubyonrails.org/active_support_core_extensions.html#descendants
2016-09-05 15:11:03 +09:00
Ryuta Kamizono
7c70430ce0 Fix broken heredoc indentation caused by rubocop auto-correct
All indentation was normalized by rubocop auto-correct at 80e66cc4d90bf8c15d1a5f6e3152e90147f00772.
But heredocs was still kept absolute position. This commit aligns
heredocs indentation for consistency.
2016-09-03 13:28:46 +09:00
Xavier Noria
bb1ecdcc67 fixes remaining RuboCop issues [Vipul A M, Xavier Noria] 2016-09-01 23:41:49 +02:00
Andrew White
8c402ef425 Cache to_datetime for performance
As demonstrated in #25880 the to_time method converts the utc time
instance to a local time instance which is an expensive operation.
Since to_datetime involves similar expensive operations we should
also cache it to speed up comparison with lots of values.
2016-09-01 13:19:42 +01:00
Vipul A M
79c847892f
Start passing cipher from EncryptedCookieJar since we use it to determine key length 2016-09-01 03:00:10 +05:30
yuuji.yaginuma
392d03a292 use message that specified in argument to error message 2016-08-31 08:52:23 +09:00
Andrew White
3132fa6b7d Merge pull request #25880 from ryandv/fix_performance_regression_in_timewithzone_to_time
Fix performance regression in `TimeWithZone#to_time`
2016-08-30 08:42:45 +01:00
yuuji.yaginuma
6582c7c54a use inspect for show from value
If `from` is nil, in order to avoid the blank is showed.
2016-08-29 09:06:10 +09:00
Anton Davydov
aa595909bf Fix typo in Delegation#delegate_missing_to doc [skip ci] 2016-08-27 14:47:17 +03:00
Santosh Wadghule
3cece0b657 Move custom assertion to its proper place
ActiveSupport::Testing::Assertions.

We have a separate module in which have defined Rails' own custom
assertions. So it would be good to keep all custom Rails' assertions in
one place i.e. in this module.
2016-08-27 08:33:08 +05:30
Ryan De Villa
af054a5ae9 Memoize coerced TimeWithZone value in TimeWithZone#localtime. 2016-08-23 14:07:07 -04:00
Ryan De Villa
fa9f1538f0 Fix performance regression in TimeWithZone#to_time
A performance regression was introduced by commit b79adc4323ff289aed3f5787fdfbb9542aa4f89f
from Rails 4.0.0.beta1, in which `TimeWithZone#to_time` no longer returns a
cached instance attribute but instead coerces the value to `Time`. This
coerced value is not cached, and recomputation degrades the performance
of comparisons between TimeWithZone objects.

See b79adc4323 (diff-3497a506c921a3a3e40fd517e92e4fe3R322)
for the change in question.

The following benchmark, which reverts the change linked above, demonstrates
the performance regression:

    require 'active_support/time'
    require 'benchmark/ips'

    utc = Time.utc(2000, 1, 1, 0)
    time_zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']

    twz = ActiveSupport::TimeWithZone.new(utc, time_zone)
    twz2 = ActiveSupport::TimeWithZone.new(Time.utc(1999, 12, 31, 23, 59, 59), ActiveSupport::TimeZone['UTC'])

    patchedTimeWithZone = Class.new(ActiveSupport::TimeWithZone) do
      def to_time
        utc
      end
    end

    patched_twz = patchedTimeWithZone.new(utc, time_zone)
    patched_twz2 = patchedTimeWithZone.new(Time.utc(1999, 12, 31, 23, 59, 59), ActiveSupport::TimeZone['UTC'])

    Benchmark.ips do |x|
      x.report("comparison out of the box") { twz <=> twz2 }
      x.report("comparison reverting to_time") { patched_twz <=> patched_twz2 }
      x.compare!
    end

The results, when run in rails-dev-box, are as follows:

    Warming up --------------------------------------
    comparison out of the box
                            24.765k i/100ms
    comparison reverting to_time
                            57.237k i/100ms
    Calculating -------------------------------------
    comparison out of the box
                            517.245k (± 4.7%) i/s -      2.600M in   5.038700s
    comparison reverting to_time
                              2.624M (± 5.0%) i/s -     13.050M in   4.985808s

    Comparison:
    comparison reverting to_time:  2624266.1 i/s
    comparison out of the box:   517244.6 i/s - 5.07x slower

The change made to run the benchmark, however, is not possible, as it would
undo the intent to standardize the return value of `to_time` to `Time` in
the system timezone.

Our proposed solution is to restore the caching behaviour of `to_time`
as it existed prior to the change linked above.

Benchmark of our solution:

    require 'active_support/time'
    require 'benchmark/ips'

    patchedTimeWithZone = Class.new(ActiveSupport::TimeWithZone) do
      def to_time
        @to_time ||= super
      end
    end

    utc = Time.utc(2000, 1, 1, 0)
    time_zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']

    twz = ActiveSupport::TimeWithZone.new(utc, time_zone)
    twz2 = ActiveSupport::TimeWithZone.new(Time.utc(1999, 12, 31, 23, 59, 59), ActiveSupport::TimeZone['UTC'])

    patched_twz = patchedTimeWithZone.new(utc, time_zone)
    patched_twz2 = patchedTimeWithZone.new(Time.utc(1999, 12, 31, 23, 59, 59), ActiveSupport::TimeZone['UTC'])

    Benchmark.ips do |x|
      x.report("TimeWithZone comparison - existing implementation") { twz <=> twz2 }
      x.report("TimeWithZone comparison - caching implementation") { patched_twz <=> patched_twz2 }
      x.compare!
    end

Results in rails-dev-box:

    Warming up --------------------------------------
    TimeWithZone comparison - existing implementation
                            26.629k i/100ms
    TimeWithZone comparison - caching implementation
                            59.144k i/100ms
    Calculating -------------------------------------
    TimeWithZone comparison - existing implementation
                            489.757k (± 4.2%) i/s -      2.450M in   5.011639s
    TimeWithZone comparison - caching implementation
                              2.802M (± 5.3%) i/s -     13.958M in   4.996116s

    Comparison:
    TimeWithZone comparison - caching implementation:  2801519.1 i/s
    TimeWithZone comparison - existing implementation:   489756.7 i/s - 5.72x slower
2016-08-23 14:07:07 -04:00
Rafael Mendonça França
32e25e812d
Merge pull request #25628 from ysksn/options
Remove parameter "options = nil" for #clear
2016-08-17 02:55:58 -03:00
Rafael Mendonça França
55f9b8129a
Add three new rubocop rules
Style/SpaceBeforeBlockBraces
Style/SpaceInsideBlockBraces
Style/SpaceInsideHashLiteralBraces

Fix all violations in the repository.
2016-08-16 04:30:11 -03:00
Eileen M. Uchitelle
22996ca6ab Merge pull request #25570 from y-yagi/remove_useless_parameter
remove useless parameter
2016-08-15 11:45:40 -04:00
mrageh
3bbd2d4dff
Add documentation about ActiveSupport.on_load
[ci skip]

This commit adds some docs that explain how `LazyLoadHooks.on_load` method
works.
2016-08-13 01:01:21 +01:00
Xavier Noria
996a27ec3a let instance thread_mattr_* methods delegate to the class-level ones
This code has too much duplication and the rationale for the concatenation
may not be obvious to the reader. You define the ones at class-level, explain
why does the code concatenates there, and then the convenience ones at
instance-level just delegate.
2016-08-08 16:01:37 +02:00
Yves Senn
e9852c92bf Merge pull request #25681 from willnet/fix-thread_mattr_accessor
Fix `thread_mattr_accessor` share variable superclass with subclass
2016-08-08 12:35:29 +02:00
Xavier Noria
628474f2d3 damn typos [ci skip] 2016-08-08 01:21:27 +02:00
Xavier Noria
55dfa00976 explain why aliasing uses explicit selfs [ci skip] 2016-08-08 01:19:32 +02:00
Xavier Noria
a9dc45459a code gardening: removes redundant selfs
A few have been left for aesthetic reasons, but have made a pass
and removed most of them.

Note that if the method `foo` returns an array, `foo << 1`
is a regular push, nothing to do with assignments, so
no self required.
2016-08-08 01:12:38 +02:00
Ryuta Kamizono
762e3f05f3 Add Style/EmptyLines in .rubocop.yml and remove extra empty lines 2016-08-07 17:50:59 +09:00
Xavier Noria
b326e82dc0 applies remaining conventions across the project 2016-08-06 20:20:22 +02:00
Xavier Noria
80e66cc4d9 normalizes indentation and whitespace across the project 2016-08-06 20:16:27 +02:00
Xavier Noria
5c315a8fa6 modernizes hash syntax in activesupport 2016-08-06 19:38:33 +02:00
Xavier Noria
d66e7835be applies new string literal convention in activesupport/lib
The current code base is not uniform. After some discussion,
we have chosen to go with double quotes by default.
2016-08-06 18:10:53 +02:00
willnet
3529e58efd Fix thread_mattr_accessor share variable superclass with subclass
The current implementation of `thread_mattr_accessor` set variable
sharing superclass with subclass. So the method doesn't work as documented.

Precondition

    class Account
      thread_mattr_accessor :user
    end

    class Customer < Account
    end

    Account.user = "DHH"
    Account.user  #=> "DHH"
    Customer.user = "Rafael"
    Customer.user # => "Rafael"

Documented behavior

    Account.user  # => "DHH"

Actual behavior

    Account.user  # => "Rafael"

Current implementation set variable statically likes `Thread[:attr_Account_user]`,
and customer also use it.

Make variable name dynamic to use own thread-local variable.
2016-08-04 10:11:06 +09:00
Andrew White
0e762ecdc3 Add :weeks to the list of variable duration parts
Since 434df00 week durations are no longer converted to days. This means
we need to add :weeks to the parts that ActiveSupport::TimeWithZone will
consider being of variable duration to take account of DST transitions.

Fixes #26039.
2016-08-03 14:45:09 +01:00
kyatul
1f5a40469e Add documentation for ActiveSupport::StringInquirer [ci skip] 2016-08-03 12:43:52 +05:30
David Heinemeier Hansson
afc9a82567 Revert "Adds not_in? onto Object" 2016-07-29 14:45:20 -07:00
Bart de Water
73209aa7a3 Add rationale for manually checking auth_tag length, which got lost when #25874 was squashed before merging [skip ci] 2016-07-27 13:41:40 +02:00
Rafael França
0020f1a4c9 Merge pull request #25914 from jmccartie/jm/not_in
Adds `not_in?` onto Object
2016-07-22 19:48:46 -03:00
Xavier Noria
92c60f87a6 revises a regexp
The exclamation mark is not a metacharacter.
2016-07-22 23:20:25 +02:00
Xavier Noria
cfc91c31aa systematic revision of =~ usage in AS
Where appropriate prefer the more concise Regexp#match?, String#include?,
String#start_with?, and String#end_with?
2016-07-22 23:13:49 +02:00
Xavier Noria
aea0e5cd70 adds require for Regexp#match? 2016-07-22 00:33:02 +02:00
Xavier Noria
21c6f810ac revises style 2016-07-22 00:31:09 +02:00
Jon McCartie
4db6ac29f2 Adds not_in? onto Object 2016-07-21 17:23:33 -05:00
Xavier Noria
929a650080 performance boost for String#blank? in Ruby 2.4
Some casual benchmarks showed a 2x factor.

All credit goes to @nurse.
2016-07-22 00:16:24 +02:00
Xavier Noria
575dbeeefc define Range#match? if Ruby < 2.4
See the rationale in the documentation included in this patch.

We are going to gradually introduce this predicate in the code base.
2016-07-22 00:15:52 +02:00
Bart de Water
d4ea18a8cb
Allow MessageEncryptor to take advantage of authenticated encryption modes
AEAD modes like `aes-256-gcm` provide both confidentiality and data authenticity, eliminating the need to use MessageVerifier to check if the encrypted data has been tampered with.

Signed-off-by: Jeremy Daer <jeremydaer@gmail.com>
2016-07-21 10:38:33 -07:00
Genadi Samokovarov
16f24cd10f Introduce assert_changes and assert_no_changes
Those are assertions that I really do miss from the standard
`ActiveSupport::TestCase`. Think of those as a more general version of
`assert_difference` and `assert_no_difference` (those can be implemented
by assert_changes, should this change be accepted).

Why do we need those? They are useful when you want to check a
side-effect of an operation. `assert_difference` do cover a really
common case, but we `assert_changes` gives us more control. Having a
global error flag? You can test it easily with `assert_changes`. In
fact, you can be really specific about the initial state and the
terminal one.

```ruby
error = Error.new(:bad)
assert_changes -> { Error.current }, from: nil, to: error do
  expected_bad_operation
end
```

`assert_changes` follows `assert_difference` and a string can be given
for evaluation as well.

```ruby
error = Error.new(:bad)
assert_changes 'Error.current', from: nil, to: error do
  expected_bad_operation
end
```

Check out the test cases if you wanna see more examples.

🍻
2016-07-17 12:58:57 +03:00
oss92
b937c24edc Added :fallback_string option to Array#to_sentence 2016-07-13 20:19:26 +02:00
Rafael França
9be45aceba Merge pull request #25790 from mrageh/wrap-lazy-load-hooks-in-module
Wrap module around lazy load hooks
2016-07-13 01:57:54 -03:00
Akira Matsuda
0796d14211 Missing require 'active_support/multibyte/unicode' 2016-07-12 22:34:11 +09:00
John Gesimondo
424e961be7 Raise ArgumentError for bad strptime arguments 2016-07-11 20:49:21 -07:00
mrageh
949485550f
Wrap module around lazy load hooks
Fix for issue https://github.com/rails/rails/issues/25784

Prior to this commit the lazy_load_hooks.rb file contained important lazy load
hooks. Since [7c90d91](7c90d91c3c) the [documentation](http://api.rubyonrails.org/files/activesupport/lib/active_support/lazy_load_hooks_rb.html) did not display
the comments in this file as the docs for load hooks.

This commit wraps the code within this file in a module so we can display the
documentation for `ActiveSupport` load hooks. By extending `ActiveSupport` with
this module, all the methods within it should still be accessible through
`ActiveSupport`.
2016-07-12 02:44:50 +01:00
Paul Sadauskas
629dde297c AS::Duration should serialize empty values correctly. (#25656)
The current implementation serializes zero-length durations incorrectly (it serializes as `"-P"`), and cannot un-serialize itself:

```
[1] pry(main)> ActiveSupport::Duration.parse(0.minutes.iso8601)
ActiveSupport::Duration::ISO8601Parser::ParsingError: Invalid ISO 8601 duration: "-P" is empty duration
from /Users/rando/.gem/ruby/2.3.1/gems/activesupport-5.0.0/lib/active_support/duration/iso8601_parser.rb:96:in `raise_parsing_error'
```

Postgres empty intervals are serialized as `"PT0S"`, which is also parseable by the Duration deserializer, so I've modified the `ISO8601Serializer` to do the same.

Additionally, the `#normalize` function returned a negative sign if `parts` was blank (all zero). Even though this fix does not rely on the sign, I've gone ahead and corrected that, too, in case a future refactoring of `#serialize` uses it.
2016-07-11 15:45:04 -04:00
John Gesimondo
39d84608ad Update class_attribute docs 2016-07-10 19:04:18 -07:00
Vipul A M
919e705362
travel/travel_to travel time helpers, now raise on nested calls,
as this can lead to confusing time stubbing.

     Instead of:

         travel_to 2.days.from_now do
           # 2 days from today
           travel_to 3.days.from_now do
             # 5 days from today
           end
         end

     preferred way to achieve above is:

         travel_to 2.days.from_now
         # 2 days from today

         travel_back
         travel_to 5.days.from_now
         # 5 days from today

Closes #24690
Fixes #24689
2016-07-02 15:09:34 -07:00
Yosuke Kabuto
b76f82d714 Update CHANGELOG.md for #25628 [ci skip]
Move new CHANGELOG entry top [ci skip]

Remove parameter "options = nil" for #clear
2016-07-02 23:58:14 +09:00
Matthew Draper
ad95b6fc72 Merge pull request #25344 from matthewd/debug-locks
ActionDispatch::DebugLocks
2016-07-02 06:47:57 +09:30
Matthew Draper
f0c7e2b8c3 Merge pull request #24146 from matthewd/latch-as-proxy
Don't inherit from Concurrent::CountDownLatch
2016-07-02 06:47:38 +09:30
Vipul A M
d7a7a2561a Merge pull request #25600 from pan/constantize-docfix
fix ActiveSupport::Infector.constantize usage API doc [ci skip]
2016-07-01 13:20:02 -07:00
Matthew Draper
ea7fee03f7 Partially revert #25192
KeyGenerator is used in other contexts, and we cannot change its
output... even if it does accidentally default to generating excess key
material for our primary internal usage.
2016-07-01 01:01:45 +09:30
Pan GaoYong
37232f6d43 fix ActiveSupport::Infector.constantize usage API doc [ci skip] 2016-06-30 22:37:49 +08:00
yuuji.yaginuma
738156f9ee remove useless parameter 2016-06-29 22:27:37 +09:00
Vipul A M
8ee269cf51
We default to using aes-256-cbc as our verification/signing cipher. It can accept key lengths of 128, 192 or 256-bit, whereas currently we were providing twice the acceptable value.
ruby < 2.4 allowed accepting these values, as extra key bits were ignored. Since ce635262f5 this now has a strict checking on key length.

Default to key length 32 bytes, to match the compatible length for  aes-256-cbc

Fixes #25185
2016-06-27 17:43:55 -07:00
Ryunosuke Sato
abbf00e583 Define Pathname#as_json
When the Pathname object is converted as JSON,
it should be a string that means itself.

Expected:
```
>> Pathname.new('/path/to/somewhere.txt').as_json
"/path/to/somewhere.txt"
```

Actual:
```
>> Pathname.new('/path/to/somewhere.txt').as_json
{"path"=>"/path/to/somewhere.txt"}
```
2016-06-25 21:50:16 +09:00
Ryunosuke Sato
236e616688 Define URI::Generic#as_json
When the URI object is converted as JSON,
it is expected that it is a string that means its URI.

Expected:
```
>> URI.parse('http://example.com').as_json
"http://example.com"
```

Actual:
```
>> URI.parse('http://example.com').as_json
{"scheme"=>"http",
 "user"=>nil,
 "password"=>nil,
 "host"=>"example.com",
 "port"=>80,
 "path"=>"",
 "query"=>nil,
 "opaque"=>nil,
 "fragment"=>nil,
 "parser"=>
  {"regexp"=>
    {"SCHEME"=>"(?-mix:\\A[A-Za-z][A-Za-z0-9+\\-.]*\\z)",
     "USERINFO"=>"(?-mix:\\A(?:%\\h\\h|[!$&-.0-;=A-Z_a-z~])*\\z)",
     "HOST"=>
      "(?-mix:\\A(?:(?<IP-literal>\\[(?:(?<IPv6address>(?:\\h{1,4}:){6}(?<ls32>\\h{1,4}:\\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5]|\\d)\\.\\g<dec-octet>\\.\\g<dec-octet>\\.\\g<dec-octet>))|::(?:\\h{1,4}:){5}\\g<ls32>|\\h{,4}::(?:\\h{1,4}:){4}\\g<ls32>|(?:(?:\\h{1,4}:)?\\h{1,4})?::(?:\\h{1,4}:){3}\\g<ls32>|(?:(?:\\h{1,4}:){,2}\\h{1,4})?::(?:\\h{1,4}:){2}\\g<ls32>|(?:(?:\\h{1,4}:){,3}\\h{1,4})?::\\h{1,4}:\\g<ls32>|(?:(?:\\h{1,4}:){,4}\\h{1,4})?::\\g<ls32>|(?:(?:\\h{1,4}:){,5}\\h{1,4})?::\\h{1,4}|(?:(?:\\h{1,4}:){,6}\\h{1,4})?::)|(?<IPvFuture>v\\h+\\.[!$&-.0-;=A-Z_a-z~]+))\\])|\\g<IPv4address>|(?<reg-name>(?:%\\h\\h|[!$&-.0-9;=A-Z_a-z~])*))\\z)",
     "ABS_PATH"=>
      "(?-mix:\\A\\/(?:%\\h\\h|[!$&-.0-;=@-Z_a-z~])*(?:\\/(?:%\\h\\h|[!$&-.0-;=@-Z_a-z~])*)*\\z)",
     "REL_PATH"=>
      "(?-mix:\\A(?:%\\h\\h|[!$&-.0-;=@-Z_a-z~])+(?:\\/(?:%\\h\\h|[!$&-.0-;=@-Z_a-z~])*)*\\z)",
     "QUERY"=>"(?-mix:\\A(?:%\\h\\h|[!$&-.0-;=@-Z_a-z~\\/?])*\\z)",
     "FRAGMENT"=>"(?-mix:\\A(?:%\\h\\h|[!$&-.0-;=@-Z_a-z~\\/?])*\\z)",
     "OPAQUE"=>"(?-mix:\\A(?:[^\\/].*)?\\z)",
     "PORT"=>
      "(?-mix:\\A[\\x09\\x0a\\x0c\\x0d ]*\\d*[\\x09\\x0a\\x0c\\x0d ]*\\z)"}}}
```
2016-06-25 16:43:58 +09:00
Godfrey Chan
3a9428df91 Merge pull request #23011 from arnvald/bugfix/correctly_parse_date
Use correct timezone when parsing date in json
2016-06-25 12:02:07 +08:00
Alex Kitchens
64cabcd77a [ci skip] Add link to method referenced in ActiveSupport::PerThreadRegistry 2016-06-24 15:14:50 -05:00
aarongray
b30805bd46 Create times in rails timezone not system timezone [ci skip]
Time.new is a Ruby method that uses system timezone. Traveling in time
using it is a recipe for confusion. Instead, Time.zone.local should
be used since it uses the Rails timezone.
2016-06-21 17:22:56 -06:00
Sean Griffin
30dd8b2cb0 Merge pull request #25302 from schneems/schneems/evented-file-boot-at-check-time-master
EventedFileUpdateChecker boots once per process
2016-06-17 10:19:56 -04:00
Alex Kitchens
9bcaa2c154 Change AS::Callback to ActiveSupport::Callbacks in doc [ci skip] 2016-06-14 14:08:33 -05:00
Rafael Mendonça França
6e5b0a184d
Fix missing requires for object/blank 2016-06-13 13:01:32 -04:00
Rafael Mendonça França
4a7cd700b4
Remove deprecated arguments in assert_nothing_raised 2016-06-13 12:05:33 -04:00
schneems
844af9fa7c Lock the whole boot step, get rid of unneeded hash 2016-06-13 09:29:57 -05:00
Genadi Samokovarov
3d8b238dd8 Remove an unused require in ActiveSupport::TestCase
We used to have `assert_blank` and `assert_presence`. [ci skip]
2016-06-13 10:50:48 +03:00
Jon Moss
02a6452e2c
Remove _run_class_setup
Should have been removed by 3073c531983de243219fb55be93fbcebfdd9c44e.
2016-06-10 21:14:33 -04:00
Rafael Mendonça França
1de3db9046
Make sure the yielded variable is the logger 2016-06-10 13:30:50 -04:00
Rafael França
1f452f9a3d Merge pull request #25341 from kmcphillips/master
Broadcast #silence on ActiveSupport::Logger
2016-06-10 13:06:44 -04:00
Rafael França
7fd477c0f5 Merge pull request #25352 from Shopify/optimized-delegate
Replace Kernel#caller by the faster Kernel#caller_locations
2016-06-10 13:04:50 -04:00
Jean Boussier
e8148a5cf4 Replace Kernel#caller by the faster Kernel#caller_locations 2016-06-10 11:34:18 -04:00
Edouard CHIN
3da701dd3c [ci skip] define_model_callbacks only exist in active model:
- Also added a note when calling multiple time `define_callbacks`
2016-06-10 11:31:11 -04:00
Matthew Draper
04b4a0666b Provide a middleware to debug misbehaving locks
Only intended to be enabled when in use; by necessity, it sits above any
reasonable access control.
2016-06-10 19:33:38 +09:30
Kevin McPhillips
99bd118eec Broadcast #silence on logger. Rewrite tests. 2016-06-09 22:10:47 -04:00
Kasper Timm Hansen
26cb88577a Merge pull request #25265 from opti/improve/hash_compact
Improve Hash#compact! documentation and tests
2016-06-07 19:46:30 +02:00
schneems
a8f29f6455 Listen earlier in EventedFileUpdateChecker
Some files like routes.rb may be very large and vary between the initialization of the app and the first request. In these scenarios if we are using a forked process we cannot rely on the files to be unchanged between when the code is booted and the listener is started. 

For that reason we start a listener on the main process immediately, when we detect that a process does not have a listener started we force the updated state to be true, so we are guaranteed to catch any changes made between the code initialization and the fork.
2016-06-06 15:24:56 -05:00
schneems
bd38e92b41 [ci skip] document EventedFileUpdateChecker 2016-06-06 11:34:39 -05:00
schneems
7bd4199448 EventedFileUpdateChecker boots once per process
We need one file checker booted per process as talked about in #24990. Before we do a check to see if any updates have been registered by the listener we first check to make sure that the current process has booted a listener.

We are intentionally not starting a listener when the checker is created. This way we can avoid #25259 in which puma warns of multiple threads created before fork. As written the listener for each process will be invoked by the `ActionDispatch::Executor` middleware when the `updated?` method is called. This is the first middleware on the stack and will be invoked before application code is read into memory.

The downside of this approach is that the API is a little less obvious. I.e. that you have to call `updated?` to get the listener to start is not intuitive. We could make `boot!` not private if we want to make the API a little nicer. Alternatively we could boot when the checker is initialized however this reintroduces the puma threads warning, and also means that in cases of `rails server` or when using `preload!` that we have extra threads notifying of changes on a process that we don't care about.

[close #24990] [close #25259]
2016-06-06 11:34:32 -05:00
Dimitris Zorbas
f484bb068b Change doc for race_condition_ttl option of ActiveSupport::Cache::Store#fetch [ci skip]
The related option of this method, `expires_in` is documented
as expecting an `ActiveSupport::Duration` value. To minimize any sort of
ambiguity between duration options, this change also documents
`race_condition_ttl` accepting `ActiveSupport::Duration`.
2016-06-06 09:25:18 +03:00
Eileen M. Uchitelle
755f6bf3d3 Merge pull request #25263 from abhishekjain16/doc_accessor_thread
[skip ci] Fix grammar
2016-06-03 10:21:49 -04:00
Abhishek Jain
f7b850ec9f [skip ci] Fix grammar 2016-06-03 19:48:26 +05:30
Vijay Dev
4e85538ddd Merge branch 'master' of github.com:rails/docrails
Conflicts:
	guides/source/action_cable_overview.md
2016-06-03 14:00:47 +00:00
Igor Pstyga
0dd23446a3
Improve Hash#compact! documentation and tests
Make it clear what should be returned when no changes were made to the
hash.

  { c: true }.compact! # => nil
2016-06-03 04:54:34 -07:00
Sean Griffin
2c5a8ba6f6 Don't blank pad day of the month when formatting dates
We are currently using `%e` which adds a space before the result if the
digit is a single number. This leads to strings like `February  2, 2016`
which is undesireable. I've opted to replace with 0 padding instead of
removing the padding entirely, to preserve compatibility for those
relying on the fact that the width is constant, and to be consistent
with time formatting.

Fixes #25251.
2016-06-02 11:47:22 -04:00
Vipul A M
4ab1f7d0bb
use OpenSSL::Cipher instead of deprecated OpenSSL::Cipher::Cipher for cipher creation.
Based on https://github.com/rails/rails/pull/25192#discussion_r65018222 and http://ruby-doc.org/stdlib-1.9.3/libdoc/openssl/rdoc/OpenSSL/Cipher/Cipher.html
2016-05-29 19:49:16 -07:00
Jon Moss
3b1b957b6f
behaviour --> behavior
http://edgeguides.rubyonrails.org/api_documentation_guidelines.html#english
2016-05-27 22:10:45 -04:00
Mark Lee
be1b716d77 Normalize whitespace for Hash#compact documentation [ci skip]
This is a similar change that occurred for Hash#except in #21087.
2016-05-24 15:40:45 -07:00