From a53ad5bba37199047ba20194933e122bf6b0252f Mon Sep 17 00:00:00 2001 From: Nahum Wild Date: Thu, 15 Jan 2009 21:28:10 -0600 Subject: Added in a local per request cache to MemCacheStore. It acts as a buffer to stop unneccessary requests being sent through to memcache [#1653 state:resolved] Signed-off-by: Joshua Peek --- .../lib/active_support/cache/mem_cache_store.rb | 65 ++++++++++++++++++++-- 1 file changed, 61 insertions(+), 4 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/cache/mem_cache_store.rb b/activesupport/lib/active_support/cache/mem_cache_store.rb index f9a7fb1440..eed9faac6d 100644 --- a/activesupport/lib/active_support/cache/mem_cache_store.rb +++ b/activesupport/lib/active_support/cache/mem_cache_store.rb @@ -13,6 +13,7 @@ module ActiveSupport # server goes down, then MemCacheStore will ignore it until it goes back # online. # - Time-based expiry support. See #write and the +:expires_in+ option. + # - Per-request in memory cache for all communication with the MemCache server(s). class MemCacheStore < Store module Response # :nodoc: STORED = "STORED\r\n" @@ -22,6 +23,24 @@ module ActiveSupport DELETED = "DELETED\r\n" end + # this allows caching of the fact that there is nothing in the remote cache + NULL = 'mem_cache_store:null' + + THREAD_LOCAL_KEY = :mem_cache_store_cache + + class LocalCache + def initialize(app) + @app = app + end + + def call(env) + Thread.current[THREAD_LOCAL_KEY] = MemoryStore.new + @app.call(env) + ensure + Thread.current[THREAD_LOCAL_KEY] = nil + end + end + attr_reader :addresses # Creates a new MemCacheStore object, with the given memcached server @@ -42,7 +61,18 @@ module ActiveSupport def read(key, options = nil) # :nodoc: super - @data.get(key, raw?(options)) + + value = local_cache && local_cache.read(key) + if value == NULL + nil + elsif value.nil? + value = @data.get(key, raw?(options)) + local_cache.write(key, value || NULL) if local_cache + value + else + # forcing the value to be immutable + value.dup + end rescue MemCache::MemCacheError => e logger.error("MemCacheError (#{e}): #{e.message}") nil @@ -61,6 +91,7 @@ module ActiveSupport # memcache-client will break the connection if you send it an integer # in raw mode, so we convert it to a string to be sure it continues working. value = value.to_s if raw?(options) + local_cache.write(key, value || NULL) if local_cache response = @data.send(method, key, value, expires_in(options), raw?(options)) response == Response::STORED rescue MemCache::MemCacheError => e @@ -70,6 +101,7 @@ module ActiveSupport def delete(key, options = nil) # :nodoc: super + local_cache.write(key, NULL) if local_cache response = @data.delete(key, expires_in(options)) response == Response::DELETED rescue MemCache::MemCacheError => e @@ -80,14 +112,27 @@ module ActiveSupport def exist?(key, options = nil) # :nodoc: # Doesn't call super, cause exist? in memcache is in fact a read # But who cares? Reading is very fast anyway - !read(key, options).nil? + # Local cache is checked first, if it doesn't know then memcache itself is read from + value = local_cache.read(key) if local_cache + if value == NULL + false + elsif value + true + else + !read(key, options).nil? + end end def increment(key, amount = 1) # :nodoc: log("incrementing", key, amount) response = @data.incr(key, amount) - response == Response::NOT_FOUND ? nil : response + unless response == Response::NOT_FOUND + local_cache.write(key, response.to_s) if local_cache + response + else + nil + end rescue MemCache::MemCacheError nil end @@ -96,17 +141,25 @@ module ActiveSupport log("decrement", key, amount) response = @data.decr(key, amount) - response == Response::NOT_FOUND ? nil : response + unless response == Response::NOT_FOUND + local_cache.write(key, response.to_s) if local_cache + response + else + nil + end rescue MemCache::MemCacheError nil end def delete_matched(matcher, options = nil) # :nodoc: + # don't do any local caching at present, just pass + # through and let the error happen super raise "Not supported by Memcache" end def clear + local_cache.clear if local_cache @data.flush_all end @@ -115,6 +168,10 @@ module ActiveSupport end private + def local_cache + Thread.current[THREAD_LOCAL_KEY] + end + def expires_in(options) (options && options[:expires_in]) || 0 end -- cgit v1.2.3 From 0bed5bdb213ea68e2f167ac4f61f698f37cf2d69 Mon Sep 17 00:00:00 2001 From: Michael Koziarski Date: Fri, 16 Jan 2009 17:37:36 +1300 Subject: Properly quote json keys. According to the RFC and the json.org site all json keys must be strings, and those strings must be quoted with double quotes. [#1755 state:committed] --- activesupport/lib/active_support/json/encoders/hash.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/json/encoders/hash.rb b/activesupport/lib/active_support/json/encoders/hash.rb index b9bdd55fa5..16dc8337f5 100644 --- a/activesupport/lib/active_support/json/encoders/hash.rb +++ b/activesupport/lib/active_support/json/encoders/hash.rb @@ -5,7 +5,7 @@ class Hash # the hash keys. For example: # # { :name => "Konata Izumi", 'age' => 16, 1 => 2 }.to_json - # # => {"name": "Konata Izumi", 1: 2, "age": 16} + # # => {"name": "Konata Izumi", "1": 2, "age": 16} # # The keys in the JSON string are unordered due to the nature of hashes. # @@ -39,7 +39,7 @@ class Hash returning result = '{' do result << hash_keys.map do |key| - "#{ActiveSupport::JSON.encode(key)}: #{ActiveSupport::JSON.encode(self[key], options)}" + "#{ActiveSupport::JSON.encode(key.to_s)}: #{ActiveSupport::JSON.encode(self[key], options)}" end * ', ' result << '}' end -- cgit v1.2.3 From 452cd74d81ecfa38d0c7d3a4dc83d2b731de9e73 Mon Sep 17 00:00:00 2001 From: Brandon Keepers Date: Sun, 4 Jan 2009 14:01:23 +0000 Subject: Dup keys in OrderedHash to prevent them from being modified [#1676 state:resolved] Signed-off-by: Frederick Cheung --- activesupport/lib/active_support/ordered_hash.rb | 31 +++++++++++++++++------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/ordered_hash.rb b/activesupport/lib/active_support/ordered_hash.rb index 3def0be639..25ea505813 100644 --- a/activesupport/lib/active_support/ordered_hash.rb +++ b/activesupport/lib/active_support/ordered_hash.rb @@ -10,10 +10,14 @@ module ActiveSupport @keys = [] end + def initialize_copy(other) + super + # make a deep copy of keys + @keys = other.keys + end + def []=(key, value) - if !has_key?(key) - @keys << key - end + @keys << key if !has_key?(key) super end @@ -24,6 +28,12 @@ module ActiveSupport end super end + + def delete_if + super + sync_keys! + self + end def reject! super @@ -36,7 +46,7 @@ module ActiveSupport end def keys - @keys + @keys.dup end def values @@ -56,7 +66,7 @@ module ActiveSupport end def each - keys.each {|key| yield [key, self[key]]} + @keys.each {|key| yield [key, self[key]]} end alias_method :each_pair, :each @@ -73,13 +83,16 @@ module ActiveSupport [k, v] end + def merge!(other_hash) + other_hash.each {|k,v| self[k] = v } + self + end + def merge(other_hash) - result = dup - other_hash.each {|k,v| result[k]=v} - result + dup.merge!(other_hash) end - private + private def sync_keys! @keys.delete_if {|k| !has_key?(k)} -- cgit v1.2.3 From b08c96887538cf53670bb882e79996582375e6c9 Mon Sep 17 00:00:00 2001 From: Lourens Naude Date: Sat, 17 Jan 2009 18:05:48 -0600 Subject: Decouple the local cache strategy from MemCacheStore for reuse with other remote stores [#1653 state:resolved] Signed-off-by: Joshua Peek --- activesupport/lib/active_support/cache.rb | 4 + .../lib/active_support/cache/mem_cache_store.rb | 64 ++----------- .../active_support/cache/strategy/local_cache.rb | 104 +++++++++++++++++++++ 3 files changed, 114 insertions(+), 58 deletions(-) create mode 100644 activesupport/lib/active_support/cache/strategy/local_cache.rb (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index 6a6c861458..83174d3a85 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -10,6 +10,10 @@ module ActiveSupport autoload :MemCacheStore, 'active_support/cache/mem_cache_store' autoload :CompressedMemCacheStore, 'active_support/cache/compressed_mem_cache_store' + module Strategy + autoload :LocalCache, 'active_support/cache/strategy/local_cache' + end + # Creates a new CacheStore object according to the given options. # # If no arguments are passed to this method, then a new diff --git a/activesupport/lib/active_support/cache/mem_cache_store.rb b/activesupport/lib/active_support/cache/mem_cache_store.rb index eed9faac6d..4d8e1fdd67 100644 --- a/activesupport/lib/active_support/cache/mem_cache_store.rb +++ b/activesupport/lib/active_support/cache/mem_cache_store.rb @@ -23,24 +23,6 @@ module ActiveSupport DELETED = "DELETED\r\n" end - # this allows caching of the fact that there is nothing in the remote cache - NULL = 'mem_cache_store:null' - - THREAD_LOCAL_KEY = :mem_cache_store_cache - - class LocalCache - def initialize(app) - @app = app - end - - def call(env) - Thread.current[THREAD_LOCAL_KEY] = MemoryStore.new - @app.call(env) - ensure - Thread.current[THREAD_LOCAL_KEY] = nil - end - end - attr_reader :addresses # Creates a new MemCacheStore object, with the given memcached server @@ -57,22 +39,13 @@ module ActiveSupport addresses = ["localhost"] if addresses.empty? @addresses = addresses @data = MemCache.new(addresses, options) + + extend Strategy::LocalCache end def read(key, options = nil) # :nodoc: super - - value = local_cache && local_cache.read(key) - if value == NULL - nil - elsif value.nil? - value = @data.get(key, raw?(options)) - local_cache.write(key, value || NULL) if local_cache - value - else - # forcing the value to be immutable - value.dup - end + @data.get(key, raw?(options)) rescue MemCache::MemCacheError => e logger.error("MemCacheError (#{e}): #{e.message}") nil @@ -91,7 +64,6 @@ module ActiveSupport # memcache-client will break the connection if you send it an integer # in raw mode, so we convert it to a string to be sure it continues working. value = value.to_s if raw?(options) - local_cache.write(key, value || NULL) if local_cache response = @data.send(method, key, value, expires_in(options), raw?(options)) response == Response::STORED rescue MemCache::MemCacheError => e @@ -101,7 +73,6 @@ module ActiveSupport def delete(key, options = nil) # :nodoc: super - local_cache.write(key, NULL) if local_cache response = @data.delete(key, expires_in(options)) response == Response::DELETED rescue MemCache::MemCacheError => e @@ -113,40 +84,22 @@ module ActiveSupport # Doesn't call super, cause exist? in memcache is in fact a read # But who cares? Reading is very fast anyway # Local cache is checked first, if it doesn't know then memcache itself is read from - value = local_cache.read(key) if local_cache - if value == NULL - false - elsif value - true - else - !read(key, options).nil? - end + !read(key, options).nil? end def increment(key, amount = 1) # :nodoc: log("incrementing", key, amount) response = @data.incr(key, amount) - unless response == Response::NOT_FOUND - local_cache.write(key, response.to_s) if local_cache - response - else - nil - end + response == Response::NOT_FOUND ? nil : response rescue MemCache::MemCacheError nil end def decrement(key, amount = 1) # :nodoc: log("decrement", key, amount) - response = @data.decr(key, amount) - unless response == Response::NOT_FOUND - local_cache.write(key, response.to_s) if local_cache - response - else - nil - end + response == Response::NOT_FOUND ? nil : response rescue MemCache::MemCacheError nil end @@ -159,7 +112,6 @@ module ActiveSupport end def clear - local_cache.clear if local_cache @data.flush_all end @@ -168,10 +120,6 @@ module ActiveSupport end private - def local_cache - Thread.current[THREAD_LOCAL_KEY] - end - def expires_in(options) (options && options[:expires_in]) || 0 end diff --git a/activesupport/lib/active_support/cache/strategy/local_cache.rb b/activesupport/lib/active_support/cache/strategy/local_cache.rb new file mode 100644 index 0000000000..621358d701 --- /dev/null +++ b/activesupport/lib/active_support/cache/strategy/local_cache.rb @@ -0,0 +1,104 @@ +module ActiveSupport + module Cache + module Strategy + module LocalCache + # this allows caching of the fact that there is nothing in the remote cache + NULL = 'remote_cache_store:null' + + def with_local_cache + Thread.current[thread_local_key] = MemoryStore.new + yield + ensure + Thread.current[thread_local_key] = nil + end + + def middleware + @middleware ||= begin + klass = Class.new + klass.class_eval(<<-EOS, __FILE__, __LINE__) + def initialize(app) + @app = app + end + + def call(env) + Thread.current[:#{thread_local_key}] = MemoryStore.new + @app.call(env) + ensure + Thread.current[:#{thread_local_key}] = nil + end + EOS + klass + end + end + + def read(key, options = nil) + value = local_cache && local_cache.read(key) + if value == NULL + nil + elsif value.nil? + value = super + local_cache.write(key, value || NULL) if local_cache + value + else + # forcing the value to be immutable + value.dup + end + end + + def write(key, value, options = nil) + value = value.to_s if respond_to?(:raw?) && raw?(options) + local_cache.write(key, value || NULL) if local_cache + super + end + + def delete(key, options = nil) + local_cache.write(key, NULL) if local_cache + super + end + + def exist(key, options = nil) + value = local_cache.read(key) if local_cache + if value == NULL + false + elsif value + true + else + super + end + end + + def increment(key, amount = 1) + if value = super + local_cache.write(key, value.to_s) if local_cache + value + else + nil + end + end + + def decrement(key, amount = 1) + if value = super + local_cache.write(key, value.to_s) if local_cache + value + else + nil + end + end + + def clear + local_cache.clear if local_cache + super + end + + private + def thread_local_key + @thread_local_key ||= "#{self.class.name.underscore}_local_cache".gsub("/", "_").to_sym + end + + def local_cache + Thread.current[thread_local_key] + end + end + end + end +end -- cgit v1.2.3 From 78f2c19ae7f9236591c261eecdf0c4b570e3ea1e Mon Sep 17 00:00:00 2001 From: Josh Susser Date: Fri, 16 Jan 2009 17:26:08 -0800 Subject: Refactor Object#try to use inheritance. [#1774 state:resolved] Signed-off-by: Pratik Naik --- .../lib/active_support/core_ext/object/misc.rb | 17 ------------ activesupport/lib/active_support/core_ext/try.rb | 30 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 17 deletions(-) create mode 100644 activesupport/lib/active_support/core_ext/try.rb (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/core_ext/object/misc.rb b/activesupport/lib/active_support/core_ext/object/misc.rb index c0a109ecf3..4acdfa3d6c 100644 --- a/activesupport/lib/active_support/core_ext/object/misc.rb +++ b/activesupport/lib/active_support/core_ext/object/misc.rb @@ -87,21 +87,4 @@ class Object respond_to? "acts_like_#{duck}?" end - # Tries to send the method only if object responds to it. Return +nil+ otherwise. - # It will also forward any arguments and/or block like Object#send does. - # - # ==== Example : - # - # # Without try - # @person ? @person.name : nil - # - # With try - # @person.try(:name) - # - # # try also accepts arguments/blocks for the method it is trying - # Person.try(:find, 1) - # @people.try(:map) {|p| p.name} - def try(method, *args, &block) - send(method, *args, &block) unless self.nil? - end end diff --git a/activesupport/lib/active_support/core_ext/try.rb b/activesupport/lib/active_support/core_ext/try.rb new file mode 100644 index 0000000000..0dccd40c55 --- /dev/null +++ b/activesupport/lib/active_support/core_ext/try.rb @@ -0,0 +1,30 @@ +class Object + # Tries to send the method only if object responds to it. Return +nil+ otherwise. + # It will also forward any arguments and/or block like Object#send does. + # + # ==== Examples + # + # Without try + # @person && @person.name + # or + # @person ? @person.name : nil + # + # With try + # @person.try(:name) + # + # Try also accepts arguments/blocks for the method it is trying + # Person.try(:find, 1) + # @people.try(:collect) {|p| p.name} + #-- + # This method def is for rdoc only. The alias_method below overrides it as an optimization. + def try(method, *args, &block) + send(method, *args, &block) + end + alias_method :try, :__send__ +end + +class NilClass + def try(*args) + nil + end +end -- cgit v1.2.3 From 39e1ac658efc80e4c54abef4f1c7679e4b3dc2ac Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sun, 18 Jan 2009 18:10:58 +0000 Subject: Merge docrails --- activesupport/lib/active_support/core_ext/date/conversions.rb | 6 +++--- activesupport/lib/active_support/core_ext/date_time/conversions.rb | 2 +- activesupport/lib/active_support/core_ext/hash/conversions.rb | 2 +- activesupport/lib/active_support/core_ext/hash/keys.rb | 2 +- activesupport/lib/active_support/core_ext/range/conversions.rb | 2 +- activesupport/lib/active_support/json/encoders/date.rb | 2 +- activesupport/lib/active_support/json/encoders/date_time.rb | 2 +- activesupport/lib/active_support/json/encoders/time.rb | 2 +- activesupport/lib/active_support/time_with_zone.rb | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/core_ext/date/conversions.rb b/activesupport/lib/active_support/core_ext/date/conversions.rb index d2d9699d01..8d9f023361 100644 --- a/activesupport/lib/active_support/core_ext/date/conversions.rb +++ b/activesupport/lib/active_support/core_ext/date/conversions.rb @@ -31,7 +31,7 @@ module ActiveSupport #:nodoc: # # This method is aliased to to_s. # - # ==== Examples: + # ==== Examples # date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007 # # date.to_formatted_s(:db) # => "2007-11-10" @@ -76,7 +76,7 @@ module ActiveSupport #:nodoc: # Converts a Date instance to a Time, where the time is set to the beginning of the day. # The timezone can be either :local or :utc (default :local). # - # ==== Examples: + # ==== Examples # date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007 # # date.to_time # => Sat Nov 10 00:00:00 0800 2007 @@ -90,7 +90,7 @@ module ActiveSupport #:nodoc: # Converts a Date instance to a DateTime, where the time is set to the beginning of the day # and UTC offset is set to 0. # - # ==== Example: + # ==== Examples # date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007 # # date.to_datetime # => Sat, 10 Nov 2007 00:00:00 0000 diff --git a/activesupport/lib/active_support/core_ext/date_time/conversions.rb b/activesupport/lib/active_support/core_ext/date_time/conversions.rb index c0175a5f28..7c948267b3 100644 --- a/activesupport/lib/active_support/core_ext/date_time/conversions.rb +++ b/activesupport/lib/active_support/core_ext/date_time/conversions.rb @@ -25,7 +25,7 @@ module ActiveSupport #:nodoc: # # This method is aliased to to_s. # - # === Examples: + # === Examples # datetime = DateTime.civil(2007, 12, 4, 0, 0, 0, 0) # => Tue, 04 Dec 2007 00:00:00 +0000 # # datetime.to_formatted_s(:db) # => "2007-12-04 00:00:00" diff --git a/activesupport/lib/active_support/core_ext/hash/conversions.rb b/activesupport/lib/active_support/core_ext/hash/conversions.rb index a254e45624..991a5a6a89 100644 --- a/activesupport/lib/active_support/core_ext/hash/conversions.rb +++ b/activesupport/lib/active_support/core_ext/hash/conversions.rb @@ -75,7 +75,7 @@ module ActiveSupport #:nodoc: # Converts a hash into a string suitable for use as a URL query string. An optional namespace can be # passed to enclose the param names (see example below). # - # ==== Example: + # ==== Examples # { :name => 'David', :nationality => 'Danish' }.to_query # => "name=David&nationality=Danish" # # { :name => 'David', :nationality => 'Danish' }.to_query('user') # => "user%5Bname%5D=David&user%5Bnationality%5D=Danish" diff --git a/activesupport/lib/active_support/core_ext/hash/keys.rb b/activesupport/lib/active_support/core_ext/hash/keys.rb index 7312bcb416..af9d372d76 100644 --- a/activesupport/lib/active_support/core_ext/hash/keys.rb +++ b/activesupport/lib/active_support/core_ext/hash/keys.rb @@ -38,7 +38,7 @@ module ActiveSupport #:nodoc: # Note that keys are NOT treated indifferently, meaning if you use strings for keys but assert symbols # as keys, this will fail. # - # ==== Examples: + # ==== Examples # { :name => "Rob", :years => "28" }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key(s): years" # { :name => "Rob", :age => "28" }.assert_valid_keys("name", "age") # => raises "ArgumentError: Unknown key(s): name, age" # { :name => "Rob", :age => "28" }.assert_valid_keys(:name, :age) # => passes, raises nothing diff --git a/activesupport/lib/active_support/core_ext/range/conversions.rb b/activesupport/lib/active_support/core_ext/range/conversions.rb index 932bdedad3..45b0826b62 100644 --- a/activesupport/lib/active_support/core_ext/range/conversions.rb +++ b/activesupport/lib/active_support/core_ext/range/conversions.rb @@ -15,7 +15,7 @@ module ActiveSupport #:nodoc: end # Gives a human readable format of the range. # - # ==== Example: + # ==== Example # # [1..100].to_formatted_s # => "1..100" def to_formatted_s(format = :default) diff --git a/activesupport/lib/active_support/json/encoders/date.rb b/activesupport/lib/active_support/json/encoders/date.rb index 1fc99c466f..cc84de1388 100644 --- a/activesupport/lib/active_support/json/encoders/date.rb +++ b/activesupport/lib/active_support/json/encoders/date.rb @@ -2,7 +2,7 @@ class Date # Returns a JSON string representing the date. If ActiveSupport.use_standard_json_time_format is set to true, the # ISO 8601 format is used. # - # ==== Examples: + # ==== Examples # # # With ActiveSupport.use_standard_json_time_format = true # Date.new(2005,2,1).to_json diff --git a/activesupport/lib/active_support/json/encoders/date_time.rb b/activesupport/lib/active_support/json/encoders/date_time.rb index e259930033..6c85824105 100644 --- a/activesupport/lib/active_support/json/encoders/date_time.rb +++ b/activesupport/lib/active_support/json/encoders/date_time.rb @@ -2,7 +2,7 @@ class DateTime # Returns a JSON string representing the datetime. If ActiveSupport.use_standard_json_time_format is set to true, the # ISO 8601 format is used. # - # ==== Examples: + # ==== Examples # # # With ActiveSupport.use_standard_json_time_format = true # DateTime.civil(2005,2,1,15,15,10).to_json diff --git a/activesupport/lib/active_support/json/encoders/time.rb b/activesupport/lib/active_support/json/encoders/time.rb index 09fc614889..f45a0059e8 100644 --- a/activesupport/lib/active_support/json/encoders/time.rb +++ b/activesupport/lib/active_support/json/encoders/time.rb @@ -2,7 +2,7 @@ class Time # Returns a JSON string representing the time. If ActiveSupport.use_standard_json_time_format is set to true, the # ISO 8601 format is used. # - # ==== Examples: + # ==== Examples # # # With ActiveSupport.use_standard_json_time_format = true # Time.utc(2005,2,1,15,15,10).to_json diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb index ec28f9801a..1a59b2a08d 100644 --- a/activesupport/lib/active_support/time_with_zone.rb +++ b/activesupport/lib/active_support/time_with_zone.rb @@ -111,7 +111,7 @@ module ActiveSupport # Returns a JSON string representing the TimeWithZone. If ActiveSupport.use_standard_json_time_format is set to # true, the ISO 8601 format is used. # - # ==== Examples: + # ==== Examples # # # With ActiveSupport.use_standard_json_time_format = true # Time.utc(2005,2,1,15,15,10).in_time_zone.to_json -- cgit v1.2.3 From f4bf318db061daa8c6ebb2b700fd15034e031310 Mon Sep 17 00:00:00 2001 From: Greg Borenstein Date: Mon, 19 Jan 2009 11:44:55 -0800 Subject: add an inspect method to OrderedHash to make it clear that it is not a species of Array Signed-off-by: Michael Koziarski [#1782 state:committed] --- activesupport/lib/active_support/ordered_hash.rb | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/ordered_hash.rb b/activesupport/lib/active_support/ordered_hash.rb index 25ea505813..66aab9e562 100644 --- a/activesupport/lib/active_support/ordered_hash.rb +++ b/activesupport/lib/active_support/ordered_hash.rb @@ -92,6 +92,10 @@ module ActiveSupport dup.merge!(other_hash) end + def inspect + "#" + end + private def sync_keys! -- cgit v1.2.3 From 5c062bf1000886d26b3a4c3b08dfb6618a4adcdf Mon Sep 17 00:00:00 2001 From: Sven Fuchs Date: Thu, 8 Jan 2009 22:14:24 -0600 Subject: add #available_locales to I18n and I18n::SimpleBackend, flatten translations load_path when loading translations [#1714 state:resolved] Signed-off-by: Joshua Peek --- .../active_support/vendor/i18n-0.1.1/lib/i18n.rb | 5 +++++ .../vendor/i18n-0.1.1/lib/i18n/backend/simple.rb | 8 +++++++- .../vendor/i18n-0.1.1/test/simple_backend_test.rb | 22 ++++++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.1/lib/i18n.rb b/activesupport/lib/active_support/vendor/i18n-0.1.1/lib/i18n.rb index b5ad094d0e..76361bed90 100755 --- a/activesupport/lib/active_support/vendor/i18n-0.1.1/lib/i18n.rb +++ b/activesupport/lib/active_support/vendor/i18n-0.1.1/lib/i18n.rb @@ -45,6 +45,11 @@ module I18n Thread.current[:locale] = locale end + # Returns an array of locales for which translations are available + def available_locales + backend.available_locales + end + # Sets the exception handler. def exception_handler=(exception_handler) @@exception_handler = exception_handler diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.1/lib/i18n/backend/simple.rb b/activesupport/lib/active_support/vendor/i18n-0.1.1/lib/i18n/backend/simple.rb index d298b3a85a..b54164d496 100644 --- a/activesupport/lib/active_support/vendor/i18n-0.1.1/lib/i18n/backend/simple.rb +++ b/activesupport/lib/active_support/vendor/i18n-0.1.1/lib/i18n/backend/simple.rb @@ -69,6 +69,12 @@ module I18n @initialized ||= false end + # Returns an array of locales for which translations are available + def available_locales + init_translations unless initialized? + translations.keys + end + def reload! @initialized = false @translations = nil @@ -76,7 +82,7 @@ module I18n protected def init_translations - load_translations(*I18n.load_path) + load_translations(*I18n.load_path.flatten) @initialized = true end diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.1/test/simple_backend_test.rb b/activesupport/lib/active_support/vendor/i18n-0.1.1/test/simple_backend_test.rb index e181975f38..8ba7036abf 100644 --- a/activesupport/lib/active_support/vendor/i18n-0.1.1/test/simple_backend_test.rb +++ b/activesupport/lib/active_support/vendor/i18n-0.1.1/test/simple_backend_test.rb @@ -124,6 +124,16 @@ class I18nSimpleBackendTranslationsTest < Test::Unit::TestCase end end +class I18nSimpleBackendAvailableLocalesTest < Test::Unit::TestCase + def test_available_locales + @backend = I18n::Backend::Simple.new + @backend.store_translations 'de', :foo => 'bar' + @backend.store_translations 'en', :foo => 'foo' + + assert_equal ['de', 'en'], @backend.available_locales.map{|locale| locale.to_s }.sort + end +end + class I18nSimpleBackendTranslateTest < Test::Unit::TestCase include I18nSimpleBackendTestSetup @@ -472,6 +482,18 @@ class I18nSimpleBackendLoadTranslationsTest < Test::Unit::TestCase end end +class I18nSimpleBackendLoadPathTest < Test::Unit::TestCase + include I18nSimpleBackendTestSetup + + def test_nested_load_paths_do_not_break_locale_loading + @backend = I18n::Backend::Simple.new + I18n.load_path = [[File.dirname(__FILE__) + '/locale/en.yml']] + assert_nil backend_get_translations + assert_nothing_raised { @backend.send :init_translations } + assert_not_nil backend_get_translations + end +end + class I18nSimpleBackendReloadTranslationsTest < Test::Unit::TestCase include I18nSimpleBackendTestSetup -- cgit v1.2.3 From 2e69db18ce2815c25eee64fc2978e7f6b57f6e1f Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Wed, 28 Jan 2009 21:20:46 -0600 Subject: Only dup local cache values if duplicable [#1653 state:resolved] --- activesupport/lib/active_support/cache/strategy/local_cache.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/cache/strategy/local_cache.rb b/activesupport/lib/active_support/cache/strategy/local_cache.rb index 621358d701..d83e259a2a 100644 --- a/activesupport/lib/active_support/cache/strategy/local_cache.rb +++ b/activesupport/lib/active_support/cache/strategy/local_cache.rb @@ -41,7 +41,7 @@ module ActiveSupport value else # forcing the value to be immutable - value.dup + value.duplicable? ? value.dup : value end end -- cgit v1.2.3 From ed0e5640879fd42c00fc5900e0355a0ea1dcf2ad Mon Sep 17 00:00:00 2001 From: Charles Nutter Date: Thu, 29 Jan 2009 00:31:07 -0600 Subject: Ensure constant_watch_stack is protected by a mutex, so concurrent requires do not corrupt it. [#1816 state:committed] Signed-off-by: Jeremy Kemper --- activesupport/lib/active_support/dependencies.rb | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb index 7ce9adec2c..2badad5f5f 100644 --- a/activesupport/lib/active_support/dependencies.rb +++ b/activesupport/lib/active_support/dependencies.rb @@ -51,6 +51,9 @@ module ActiveSupport #:nodoc: mattr_accessor :constant_watch_stack self.constant_watch_stack = [] + mattr_accessor :constant_watch_stack_mutex + self.constant_watch_stack_mutex = Mutex.new + # Module includes this module module ModuleConstMissing #:nodoc: def self.included(base) #:nodoc: @@ -509,7 +512,9 @@ module ActiveSupport #:nodoc: [mod_name, initial_constants] end - constant_watch_stack.concat watch_frames + constant_watch_stack_mutex.synchronize do + constant_watch_stack.concat watch_frames + end aborting = true begin @@ -526,8 +531,10 @@ module ActiveSupport #:nodoc: new_constants = mod.local_constant_names - prior_constants # Make sure no other frames takes credit for these constants. - constant_watch_stack.each do |frame_name, constants| - constants.concat new_constants if frame_name == mod_name + constant_watch_stack_mutex.synchronize do + constant_watch_stack.each do |frame_name, constants| + constants.concat new_constants if frame_name == mod_name + end end new_constants.collect do |suffix| @@ -549,8 +556,10 @@ module ActiveSupport #:nodoc: # Remove the stack frames that we added. if defined?(watch_frames) && ! watch_frames.blank? frame_ids = watch_frames.collect { |frame| frame.object_id } - constant_watch_stack.delete_if do |watch_frame| - frame_ids.include? watch_frame.object_id + constant_watch_stack_mutex.synchronize do + constant_watch_stack.delete_if do |watch_frame| + frame_ids.include? watch_frame.object_id + end end end end -- cgit v1.2.3