aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib
diff options
context:
space:
mode:
authorPratik Naik <pratiknaik@gmail.com>2008-08-14 16:31:14 +0100
committerPratik Naik <pratiknaik@gmail.com>2008-08-14 16:31:14 +0100
commit2ebe8d275efa53af967b09ad66dab68acc1aed98 (patch)
treeb0b3e42c277b213788b55558aef3579f4e242300 /activesupport/lib
parent73ef94e9675ef6db85f18f1e3c70bf6ddfc1260a (diff)
parent8cb14ee1203c9ed380c4b192e8730757a52d43cb (diff)
downloadrails-2ebe8d275efa53af967b09ad66dab68acc1aed98.tar.gz
rails-2ebe8d275efa53af967b09ad66dab68acc1aed98.tar.bz2
rails-2ebe8d275efa53af967b09ad66dab68acc1aed98.zip
Merge commit 'mainstream/master'
Conflicts: actionpack/lib/action_controller/request.rb actionpack/lib/action_controller/resources.rb
Diffstat (limited to 'activesupport/lib')
-rw-r--r--activesupport/lib/active_support/cache.rb18
-rw-r--r--activesupport/lib/active_support/cache/compressed_mem_cache_store.rb8
-rw-r--r--activesupport/lib/active_support/cache/file_store.rb4
-rw-r--r--activesupport/lib/active_support/cache/memory_store.rb24
-rw-r--r--activesupport/lib/active_support/core_ext/file.rb24
-rw-r--r--activesupport/lib/active_support/core_ext/file/atomic.rb46
-rw-r--r--activesupport/lib/active_support/inflector.rb13
-rw-r--r--activesupport/lib/active_support/memoizable.rb58
8 files changed, 129 insertions, 66 deletions
diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb
index 5a064f8bea..95eae3a77e 100644
--- a/activesupport/lib/active_support/cache.rb
+++ b/activesupport/lib/active_support/cache.rb
@@ -39,10 +39,6 @@ module ActiveSupport
class Store
cattr_accessor :logger
- def threadsafe!
- extend ThreadSafety
- end
-
def silence!
@silence = true
self
@@ -115,20 +111,6 @@ module ActiveSupport
logger.debug("Cache #{operation}: #{key}#{options ? " (#{options.inspect})" : ""}") if logger && !@silence && !@logger_off
end
end
-
- module ThreadSafety #:nodoc:
- def self.extended(object) #:nodoc:
- object.instance_variable_set(:@mutex, Mutex.new)
- end
-
- %w(read write delete delete_matched exist? increment decrement).each do |method|
- module_eval <<-EOS, __FILE__, __LINE__
- def #{method}(*args)
- @mutex.synchronize { super }
- end
- EOS
- end
- end
end
end
diff --git a/activesupport/lib/active_support/cache/compressed_mem_cache_store.rb b/activesupport/lib/active_support/cache/compressed_mem_cache_store.rb
index 9470ac9f66..0bff6cf9ad 100644
--- a/activesupport/lib/active_support/cache/compressed_mem_cache_store.rb
+++ b/activesupport/lib/active_support/cache/compressed_mem_cache_store.rb
@@ -1,14 +1,14 @@
module ActiveSupport
module Cache
class CompressedMemCacheStore < MemCacheStore
- def read(name, options = {})
- if value = super(name, options.merge(:raw => true))
+ def read(name, options = nil)
+ if value = super(name, (options || {}).merge(:raw => true))
Marshal.load(ActiveSupport::Gzip.decompress(value))
end
end
- def write(name, value, options = {})
- super(name, ActiveSupport::Gzip.compress(Marshal.dump(value)), options.merge(:raw => true))
+ def write(name, value, options = nil)
+ super(name, ActiveSupport::Gzip.compress(Marshal.dump(value)), (options || {}).merge(:raw => true))
end
end
end
diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb
index 5b771b1da0..437679cc05 100644
--- a/activesupport/lib/active_support/cache/file_store.rb
+++ b/activesupport/lib/active_support/cache/file_store.rb
@@ -9,13 +9,13 @@ module ActiveSupport
def read(name, options = nil)
super
- File.open(real_file_path(name), 'rb') { |f| f.read } rescue nil
+ File.open(real_file_path(name), 'rb') { |f| Marshal.load(f) } rescue nil
end
def write(name, value, options = nil)
super
ensure_cache_path(File.dirname(real_file_path(name)))
- File.open(real_file_path(name), "wb+") { |f| f.write(value) }
+ File.atomic_write(real_file_path(name), cache_path) { |f| Marshal.dump(value, f) }
rescue => e
RAILS_DEFAULT_LOGGER.error "Couldn't create cache directory: #{name} (#{e.message})" if RAILS_DEFAULT_LOGGER
end
diff --git a/activesupport/lib/active_support/cache/memory_store.rb b/activesupport/lib/active_support/cache/memory_store.rb
index 6f114273e4..a44f877414 100644
--- a/activesupport/lib/active_support/cache/memory_store.rb
+++ b/activesupport/lib/active_support/cache/memory_store.rb
@@ -3,6 +3,13 @@ module ActiveSupport
class MemoryStore < Store
def initialize
@data = {}
+ @mutex = Mutex.new
+ end
+
+ def fetch(key, options = {})
+ @mutex.synchronize do
+ super
+ end
end
def read(name, options = nil)
@@ -16,23 +23,32 @@ module ActiveSupport
end
def delete(name, options = nil)
- super
@data.delete(name)
end
def delete_matched(matcher, options = nil)
- super
@data.delete_if { |k,v| k =~ matcher }
end
def exist?(name,options = nil)
- super
@data.has_key?(name)
end
+ def increment(key, amount = 1)
+ @mutex.synchronize do
+ super
+ end
+ end
+
+ def decrement(key, amount = 1)
+ @mutex.synchronize do
+ super
+ end
+ end
+
def clear
@data.clear
end
end
end
-end \ No newline at end of file
+end
diff --git a/activesupport/lib/active_support/core_ext/file.rb b/activesupport/lib/active_support/core_ext/file.rb
index 45d93b220f..e03f8ac44e 100644
--- a/activesupport/lib/active_support/core_ext/file.rb
+++ b/activesupport/lib/active_support/core_ext/file.rb
@@ -1,21 +1,5 @@
-require 'tempfile'
+require 'active_support/core_ext/file/atomic'
-# Write to a file atomically. Useful for situations where you don't
-# want other processes or threads to see half-written files.
-#
-# File.atomic_write("important.file") do |file|
-# file.write("hello")
-# end
-#
-# If your temp directory is not on the same filesystem as the file you're
-# trying to write, you can provide a different temporary directory.
-#
-# File.atomic_write("/data/something.important", "/data/tmp") do |f|
-# file.write("hello")
-# end
-def File.atomic_write(file_name, temp_dir = Dir.tmpdir)
- temp_file = Tempfile.new(File.basename(file_name), temp_dir)
- yield temp_file
- temp_file.close
- File.rename(temp_file.path, file_name)
-end \ No newline at end of file
+class File #:nodoc:
+ extend ActiveSupport::CoreExtensions::File::Atomic
+end
diff --git a/activesupport/lib/active_support/core_ext/file/atomic.rb b/activesupport/lib/active_support/core_ext/file/atomic.rb
new file mode 100644
index 0000000000..4d3cf5423f
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/file/atomic.rb
@@ -0,0 +1,46 @@
+require 'tempfile'
+
+module ActiveSupport #:nodoc:
+ module CoreExtensions #:nodoc:
+ module File #:nodoc:
+ module Atomic
+ # Write to a file atomically. Useful for situations where you don't
+ # want other processes or threads to see half-written files.
+ #
+ # File.atomic_write("important.file") do |file|
+ # file.write("hello")
+ # end
+ #
+ # If your temp directory is not on the same filesystem as the file you're
+ # trying to write, you can provide a different temporary directory.
+ #
+ # File.atomic_write("/data/something.important", "/data/tmp") do |f|
+ # file.write("hello")
+ # end
+ def atomic_write(file_name, temp_dir = Dir.tmpdir)
+ temp_file = Tempfile.new(basename(file_name), temp_dir)
+ yield temp_file
+ temp_file.close
+
+ begin
+ # Get original file permissions
+ old_stat = stat(file_name)
+ rescue Errno::ENOENT
+ # No old permissions, write a temp file to determine the defaults
+ check_name = ".permissions_check.#{Thread.current.object_id}.#{Process.pid}.#{rand(1000000)}"
+ new(check_name, "w")
+ old_stat = stat(check_name)
+ unlink(check_name)
+ end
+
+ # Overwrite original file with temp file
+ rename(temp_file.path, file_name)
+
+ # Set correct permissions on new file
+ chown(old_stat.uid, old_stat.gid, file_name)
+ chmod(old_stat.mode, file_name)
+ end
+ end
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/inflector.rb b/activesupport/lib/active_support/inflector.rb
index 6651569d33..c2738b39fc 100644
--- a/activesupport/lib/active_support/inflector.rb
+++ b/activesupport/lib/active_support/inflector.rb
@@ -291,11 +291,14 @@ module ActiveSupport
# NameError is raised when the name is not in CamelCase or the constant is
# unknown.
def constantize(camel_cased_word)
- unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ camel_cased_word
- raise NameError, "#{camel_cased_word.inspect} is not a valid constant name!"
- end
+ names = camel_cased_word.split('::')
+ names.shift if names.empty? || names.first.empty?
- Object.module_eval("::#{$1}", __FILE__, __LINE__)
+ constant = Object
+ names.each do |name|
+ constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
+ end
+ constant
end
# Turns a number into an ordinal string used to denote the position in an
@@ -326,4 +329,4 @@ require 'active_support/inflections'
require 'active_support/core_ext/string/inflections'
unless String.included_modules.include?(ActiveSupport::CoreExtensions::String::Inflections)
String.send :include, ActiveSupport::CoreExtensions::String::Inflections
-end \ No newline at end of file
+end
diff --git a/activesupport/lib/active_support/memoizable.rb b/activesupport/lib/active_support/memoizable.rb
index 23dd96e4df..6506238ac0 100644
--- a/activesupport/lib/active_support/memoizable.rb
+++ b/activesupport/lib/active_support/memoizable.rb
@@ -10,18 +10,37 @@ module ActiveSupport
end
def freeze_with_memoizable
- methods.each do |method|
- __send__($1) if method.to_s =~ /^_unmemoized_(.*)/
- end unless frozen?
-
+ memoize_all unless frozen?
freeze_without_memoizable
end
+
+ def memoize_all
+ methods.each do |m|
+ if m.to_s =~ /^_unmemoized_(.*)/
+ if method(m).arity == 0
+ __send__($1)
+ else
+ ivar = :"@_memoized_#{$1}"
+ instance_variable_set(ivar, {})
+ end
+ end
+ end
+ end
+
+ def unmemoize_all
+ methods.each do |m|
+ if m.to_s =~ /^_unmemoized_(.*)/
+ ivar = :"@_memoized_#{$1}"
+ instance_variable_get(ivar).clear if instance_variable_defined?(ivar)
+ end
+ end
+ end
end
def memoize(*symbols)
symbols.each do |symbol|
- original_method = "_unmemoized_#{symbol}"
- memoized_ivar = "@_memoized_#{symbol}"
+ original_method = :"_unmemoized_#{symbol}"
+ memoized_ivar = :"@_memoized_#{symbol.to_s.sub(/\?\Z/, '_query').sub(/!\Z/, '_bang')}"
class_eval <<-EOS, __FILE__, __LINE__
include Freezable
@@ -29,14 +48,27 @@ module ActiveSupport
raise "Already memoized #{symbol}" if method_defined?(:#{original_method})
alias #{original_method} #{symbol}
- def #{symbol}(*args)
- #{memoized_ivar} ||= {}
- reload = args.pop if args.last == true || args.last == :reload
+ if instance_method(:#{symbol}).arity == 0
+ def #{symbol}(reload = false)
+ if reload || !defined?(#{memoized_ivar}) || #{memoized_ivar}.empty?
+ #{memoized_ivar} = [#{original_method}.freeze]
+ end
+ #{memoized_ivar}[0]
+ end
+ else
+ def #{symbol}(*args)
+ #{memoized_ivar} ||= {} unless frozen?
+ reload = args.pop if args.last == true || args.last == :reload
- if !reload && #{memoized_ivar} && #{memoized_ivar}.has_key?(args)
- #{memoized_ivar}[args]
- else
- #{memoized_ivar}[args] = #{original_method}(*args).freeze
+ if #{memoized_ivar}
+ if !reload && #{memoized_ivar}.has_key?(args)
+ #{memoized_ivar}[args]
+ elsif #{memoized_ivar}
+ #{memoized_ivar}[args] = #{original_method}(*args).freeze
+ end
+ else
+ #{original_method}(*args)
+ end
end
end
EOS