diff options
Diffstat (limited to 'activesupport/lib/active_support')
14 files changed, 87 insertions, 74 deletions
diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index e8518645d9..30a69c550b 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -438,18 +438,18 @@ module ActiveSupport options = merged_options(options) instrument :read_multi, names, options do |payload| - read_multi_entries(names, options).tap do |results| - payload[:hits] = results.keys - payload[:super_operation] = :fetch_multi + reads = read_multi_entries(names, options) + writes = {} + ordered = names.each_with_object({}) do |name, hash| + hash[name] = reads.fetch(name) { writes[name] = yield(name) } + end - writes = {} + payload[:hits] = reads.keys + payload[:super_operation] = :fetch_multi - (names - results.keys).each do |name| - results[name] = writes[name] = yield(name) - end + write_multi(writes, options) - write_multi writes, options - end + ordered end end diff --git a/activesupport/lib/active_support/core_ext/date/calculations.rb b/activesupport/lib/active_support/core_ext/date/calculations.rb index 1cd7acb05d..d03a8d3997 100644 --- a/activesupport/lib/active_support/core_ext/date/calculations.rb +++ b/activesupport/lib/active_support/core_ext/date/calculations.rb @@ -110,12 +110,13 @@ class Date # Provides precise Date calculations for years, months, and days. The +options+ parameter takes a hash with # any of these keys: <tt>:years</tt>, <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>. def advance(options) - options = options.dup d = self - d = d >> options.delete(:years) * 12 if options[:years] - d = d >> options.delete(:months) if options[:months] - d = d + options.delete(:weeks) * 7 if options[:weeks] - d = d + options.delete(:days) if options[:days] + + d = d >> options[:years] * 12 if options[:years] + d = d >> options[:months] if options[:months] + d = d + options[:weeks] * 7 if options[:weeks] + d = d + options[:days] if options[:days] + d end diff --git a/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb b/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb index 05abd83221..e2e11545e2 100644 --- a/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb @@ -134,7 +134,7 @@ module DateAndTime # now = DateTime.current # => Fri, 10 Jul 2015 18:41:29 +0000 # now.beginning_of_quarter # => Wed, 01 Jul 2015 00:00:00 +0000 def beginning_of_quarter - first_quarter_month = [10, 7, 4, 1].detect { |m| m <= month } + first_quarter_month = month - (2 + month) % 3 beginning_of_month.change(month: first_quarter_month) end alias :at_beginning_of_quarter :beginning_of_quarter @@ -149,7 +149,7 @@ module DateAndTime # now = DateTime.current # => Fri, 10 Jul 2015 18:41:29 +0000 # now.end_of_quarter # => Wed, 30 Sep 2015 23:59:59 +0000 def end_of_quarter - last_quarter_month = [3, 6, 9, 12].detect { |m| m >= month } + last_quarter_month = month + (12 - month) % 3 beginning_of_month.change(month: last_quarter_month).end_of_month end alias :at_end_of_quarter :end_of_quarter diff --git a/activesupport/lib/active_support/core_ext/module.rb b/activesupport/lib/active_support/core_ext/module.rb index d91e3fba6a..542af98c04 100644 --- a/activesupport/lib/active_support/core_ext/module.rb +++ b/activesupport/lib/active_support/core_ext/module.rb @@ -3,7 +3,6 @@ require "active_support/core_ext/module/aliasing" require "active_support/core_ext/module/introspection" require "active_support/core_ext/module/anonymous" -require "active_support/core_ext/module/reachable" require "active_support/core_ext/module/attribute_accessors" require "active_support/core_ext/module/attribute_accessors_per_thread" require "active_support/core_ext/module/attr_internal" diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb index be90390ae4..5652f2d1cc 100644 --- a/activesupport/lib/active_support/core_ext/module/delegation.rb +++ b/activesupport/lib/active_support/core_ext/module/delegation.rb @@ -243,7 +243,7 @@ class Module # end # # def person - # @event.detail.person || @event.creator + # detail.person || creator # end # # private @@ -266,7 +266,7 @@ class Module # end # # def person - # @event.detail.person || @event.creator + # detail.person || creator # end # end # diff --git a/activesupport/lib/active_support/core_ext/module/reachable.rb b/activesupport/lib/active_support/core_ext/module/reachable.rb index e9cbda5245..2020f5204c 100644 --- a/activesupport/lib/active_support/core_ext/module/reachable.rb +++ b/activesupport/lib/active_support/core_ext/module/reachable.rb @@ -3,9 +3,4 @@ require "active_support/core_ext/module/anonymous" require "active_support/core_ext/string/inflections" -class Module - def reachable? #:nodoc: - !anonymous? && name.safe_constantize.equal?(self) - end - deprecate :reachable? -end +ActiveSupport::Deprecation.warn("reachable is deprecated and will be removed from the framework.") diff --git a/activesupport/lib/active_support/core_ext/securerandom.rb b/activesupport/lib/active_support/core_ext/securerandom.rb index b4a491f5fd..ef812f7e1a 100644 --- a/activesupport/lib/active_support/core_ext/securerandom.rb +++ b/activesupport/lib/active_support/core_ext/securerandom.rb @@ -4,17 +4,18 @@ require "securerandom" module SecureRandom BASE58_ALPHABET = ("0".."9").to_a + ("A".."Z").to_a + ("a".."z").to_a - ["0", "O", "I", "l"] + BASE36_ALPHABET = ("0".."9").to_a + ("a".."z").to_a + # SecureRandom.base58 generates a random base58 string. # - # The argument _n_ specifies the length, of the random string to be generated. + # The argument _n_ specifies the length of the random string to be generated. # # If _n_ is not specified or is +nil+, 16 is assumed. It may be larger in the future. # - # The result may contain alphanumeric characters except 0, O, I and l + # The result may contain alphanumeric characters except 0, O, I and l. # # p SecureRandom.base58 # => "4kUgL2pdQMSCQtjE" # p SecureRandom.base58(24) # => "77TMHrHJFvFDwodq8w7Ev2m7" - # def self.base58(n = 16) SecureRandom.random_bytes(n).unpack("C*").map do |byte| idx = byte % 64 @@ -22,4 +23,23 @@ module SecureRandom BASE58_ALPHABET[idx] end.join end + + # SecureRandom.base36 generates a random base36 string in lowercase. + # + # The argument _n_ specifies the length of the random string to be generated. + # + # If _n_ is not specified or is +nil+, 16 is assumed. It may be larger in the future. + # This method can be used over +base58+ if a deterministic case key is necessary. + # + # The result will contain alphanumeric characters in lowercase. + # + # p SecureRandom.base36 # => "4kugl2pdqmscqtje" + # p SecureRandom.base36(24) # => "77tmhrhjfvfdwodq8w7ev2m7" + def self.base36(n = 16) + SecureRandom.random_bytes(n).unpack("C*").map do |byte| + idx = byte % 64 + idx = SecureRandom.random_number(36) if idx >= 36 + BASE36_ALPHABET[idx] + end.join + end end diff --git a/activesupport/lib/active_support/duration.rb b/activesupport/lib/active_support/duration.rb index 314c926ac0..97b4634d7b 100644 --- a/activesupport/lib/active_support/duration.rb +++ b/activesupport/lib/active_support/duration.rb @@ -214,8 +214,11 @@ module ActiveSupport end def coerce(other) #:nodoc: - if Scalar === other + case other + when Scalar [other, self] + when Duration + [Scalar.new(other.value), self] else [Scalar.new(other), self] end diff --git a/activesupport/lib/active_support/gem_version.rb b/activesupport/lib/active_support/gem_version.rb index c951ad16a3..8bf016e88c 100644 --- a/activesupport/lib/active_support/gem_version.rb +++ b/activesupport/lib/active_support/gem_version.rb @@ -10,7 +10,7 @@ module ActiveSupport MAJOR = 6 MINOR = 0 TINY = 0 - PRE = "alpha" + PRE = "beta1" STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") end diff --git a/activesupport/lib/active_support/inflector/inflections.rb b/activesupport/lib/active_support/inflector/inflections.rb index fa087c4dd6..88cdd99dbd 100644 --- a/activesupport/lib/active_support/inflector/inflections.rb +++ b/activesupport/lib/active_support/inflector/inflections.rb @@ -65,8 +65,7 @@ module ActiveSupport @__instance__[locale] ||= new end - attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms, :acronym_regex - deprecate :acronym_regex + attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms attr_reader :acronyms_camelize_regex, :acronyms_underscore_regex # :nodoc: diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb index 1af9833d46..ee193add6f 100644 --- a/activesupport/lib/active_support/inflector/methods.rb +++ b/activesupport/lib/active_support/inflector/methods.rb @@ -328,6 +328,8 @@ module ActiveSupport e.name.to_s == camel_cased_word.to_s) rescue ArgumentError => e raise unless /not missing constant #{const_regexp(camel_cased_word)}!$/.match?(e.message) + rescue LoadError => e + raise unless /Unable to autoload constant #{const_regexp(camel_cased_word)}/.match?(e.message) end # Returns the suffix that should be added to a number to denote the position diff --git a/activesupport/lib/active_support/key_generator.rb b/activesupport/lib/active_support/key_generator.rb index 00edcdd05a..8b61982883 100644 --- a/activesupport/lib/active_support/key_generator.rb +++ b/activesupport/lib/active_support/key_generator.rb @@ -38,36 +38,4 @@ module ActiveSupport @cache_keys[args.join] ||= @key_generator.generate_key(*args) end end - - class LegacyKeyGenerator # :nodoc: - SECRET_MIN_LENGTH = 30 # Characters - - def initialize(secret) - ensure_secret_secure(secret) - @secret = secret - end - - def generate_key(salt) - @secret - end - - private - - # To prevent users from using something insecure like "Password" we make sure that the - # secret they've provided is at least 30 characters in length. - def ensure_secret_secure(secret) - if secret.blank? - raise ArgumentError, "A secret is required to generate an integrity hash " \ - "for cookie session data. Set a secret_key_base of at least " \ - "#{SECRET_MIN_LENGTH} characters by running `rails credentials:edit`." - end - - if secret.length < SECRET_MIN_LENGTH - raise ArgumentError, "Secret should be something secure, " \ - "like \"#{SecureRandom.hex(16)}\". The value you " \ - "provided, \"#{secret}\", is shorter than the minimum length " \ - "of #{SECRET_MIN_LENGTH} characters." - end - end - end end diff --git a/activesupport/lib/active_support/log_subscriber.rb b/activesupport/lib/active_support/log_subscriber.rb index 0f7be06c8e..938cfdb914 100644 --- a/activesupport/lib/active_support/log_subscriber.rb +++ b/activesupport/lib/active_support/log_subscriber.rb @@ -5,8 +5,8 @@ require "active_support/core_ext/class/attribute" require "active_support/subscriber" module ActiveSupport - # ActiveSupport::LogSubscriber is an object set to consume - # ActiveSupport::Notifications with the sole purpose of logging them. + # <tt>ActiveSupport::LogSubscriber</tt> is an object set to consume + # <tt>ActiveSupport::Notifications</tt> with the sole purpose of logging them. # The log subscriber dispatches notifications to a registered object based # on its given namespace. # @@ -16,7 +16,7 @@ module ActiveSupport # module ActiveRecord # class LogSubscriber < ActiveSupport::LogSubscriber # def sql(event) - # "#{event.payload[:name]} (#{event.duration}) #{event.payload[:sql]}" + # info "#{event.payload[:name]} (#{event.duration}) #{event.payload[:sql]}" # end # end # end @@ -29,13 +29,36 @@ module ActiveSupport # subscriber, the line above should be called after your # <tt>ActiveRecord::LogSubscriber</tt> definition. # - # After configured, whenever a "sql.active_record" notification is published, - # it will properly dispatch the event (ActiveSupport::Notifications::Event) to - # the sql method. + # After configured, whenever a <tt>"sql.active_record"</tt> notification is published, + # it will properly dispatch the event + # (<tt>ActiveSupport::Notifications::Event</tt>) to the sql method. + # + # Being an <tt>ActiveSupport::Notifications</tt> consumer, + # <tt>ActiveSupport::LogSubscriber</tt> exposes a simple interface to check if + # instrumented code raises an exception. It is common to log a different + # message in case of an error, and this can be achieved by extending + # the previous example: + # + # module ActiveRecord + # class LogSubscriber < ActiveSupport::LogSubscriber + # def sql(event) + # exception = event.payload[:exception] + # + # if exception + # exception_object = event.payload[:exception_object] + # + # error "[ERROR] #{event.payload[:name]}: #{exception.join(', ')} " \ + # "(#{exception_object.backtrace.first})" + # else + # # standard logger code + # end + # end + # end + # end # # Log subscriber also has some helpers to deal with logging and automatically - # flushes all logs when the request finishes (via action_dispatch.callback - # notification) in a Rails environment. + # flushes all logs when the request finishes + # (via <tt>action_dispatch.callback</tt> notification) in a Rails environment. class LogSubscriber < Subscriber # Embed in a String to clear all previous ANSI sequences. CLEAR = "\e[0m" diff --git a/activesupport/lib/active_support/notifications.rb b/activesupport/lib/active_support/notifications.rb index 0ff32bd810..7ccc333463 100644 --- a/activesupport/lib/active_support/notifications.rb +++ b/activesupport/lib/active_support/notifications.rb @@ -67,9 +67,12 @@ module ActiveSupport # have a key <tt>:exception</tt> with an array of two elements as value: a string with # the name of the exception class, and the exception message. # The <tt>:exception_object</tt> key of the payload will have the exception - # itself as the value. + # itself as the value: # - # As the previous example depicts, the class <tt>ActiveSupport::Notifications::Event</tt> + # event.payload[:exception] # => ["ArgumentError", "Invalid value"] + # event.payload[:exception_object] # => #<ArgumentError: Invalid value> + # + # As the earlier example depicts, the class <tt>ActiveSupport::Notifications::Event</tt> # is able to take the arguments as they come and provide an object-oriented # interface to that data. # |