activesupport 1.2.5 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (63) hide show
  1. data/CHANGELOG +163 -4
  2. data/lib/active_support.rb +8 -3
  3. data/lib/active_support/breakpoint.rb +1 -1
  4. data/lib/active_support/caching_tools.rb +62 -0
  5. data/lib/active_support/clean_logger.rb +3 -1
  6. data/lib/active_support/core_ext/array.rb +16 -0
  7. data/lib/active_support/core_ext/array/conversions.rb +18 -2
  8. data/lib/active_support/core_ext/blank.rb +14 -2
  9. data/lib/active_support/core_ext/class.rb +3 -0
  10. data/lib/active_support/core_ext/class/attribute_accessors.rb +44 -0
  11. data/lib/active_support/{class_inheritable_attributes.rb → core_ext/class/inheritable_attributes.rb} +2 -4
  12. data/lib/active_support/core_ext/class/removal.rb +24 -0
  13. data/lib/active_support/core_ext/date/conversions.rb +2 -0
  14. data/lib/active_support/core_ext/enumerable.rb +23 -1
  15. data/lib/active_support/core_ext/exception.rb +0 -1
  16. data/lib/active_support/core_ext/hash.rb +4 -0
  17. data/lib/active_support/core_ext/hash/conversions.rb +44 -0
  18. data/lib/active_support/core_ext/hash/diff.rb +11 -0
  19. data/lib/active_support/core_ext/hash/indifferent_access.rb +23 -4
  20. data/lib/active_support/core_ext/integer/inflections.rb +1 -1
  21. data/lib/active_support/core_ext/kernel.rb +4 -79
  22. data/lib/active_support/core_ext/kernel/agnostics.rb +11 -0
  23. data/lib/active_support/core_ext/kernel/daemonizing.rb +15 -0
  24. data/lib/active_support/core_ext/kernel/reporting.rb +51 -0
  25. data/lib/active_support/core_ext/kernel/requires.rb +24 -0
  26. data/lib/active_support/core_ext/logger.rb +16 -0
  27. data/lib/active_support/core_ext/module.rb +5 -0
  28. data/lib/active_support/core_ext/module/attribute_accessors.rb +44 -0
  29. data/lib/active_support/core_ext/module/delegation.rb +16 -0
  30. data/lib/active_support/core_ext/module/inclusion.rb +11 -0
  31. data/lib/active_support/core_ext/module/introspection.rb +21 -0
  32. data/lib/active_support/core_ext/module/loading.rb +13 -0
  33. data/lib/active_support/core_ext/numeric/time.rb +14 -1
  34. data/lib/active_support/core_ext/object.rb +2 -0
  35. data/lib/active_support/core_ext/object/extending.rb +47 -0
  36. data/lib/active_support/core_ext/object/misc.rb +34 -0
  37. data/lib/active_support/core_ext/proc.rb +12 -0
  38. data/lib/active_support/core_ext/string.rb +2 -0
  39. data/lib/active_support/core_ext/string/access.rb +2 -2
  40. data/lib/active_support/core_ext/string/inflections.rb +10 -3
  41. data/lib/active_support/core_ext/string/iterators.rb +17 -0
  42. data/lib/active_support/core_ext/symbol.rb +5 -0
  43. data/lib/active_support/core_ext/time/calculations.rb +15 -0
  44. data/lib/active_support/core_ext/time/conversions.rb +1 -0
  45. data/lib/active_support/dependencies.rb +81 -159
  46. data/lib/active_support/inflections.rb +48 -48
  47. data/lib/active_support/inflector.rb +17 -5
  48. data/lib/active_support/json.rb +37 -0
  49. data/lib/active_support/json/encoders.rb +25 -0
  50. data/lib/active_support/json/encoders/core.rb +65 -0
  51. data/lib/active_support/option_merger.rb +25 -0
  52. data/lib/active_support/ordered_options.rb +23 -11
  53. data/lib/active_support/reloadable.rb +30 -0
  54. data/lib/active_support/vendor/builder.rb +13 -0
  55. data/lib/active_support/vendor/builder/blankslate.rb +53 -0
  56. data/lib/active_support/vendor/builder/xmlbase.rb +143 -0
  57. data/lib/active_support/vendor/builder/xmlevents.rb +63 -0
  58. data/lib/active_support/vendor/builder/xmlmarkup.rb +308 -0
  59. data/lib/active_support/version.rb +2 -2
  60. metadata +113 -69
  61. data/lib/active_support/class_attribute_accessors.rb +0 -57
  62. data/lib/active_support/core_ext/object_and_class.rb +0 -44
  63. data/lib/active_support/module_attribute_accessors.rb +0 -57
@@ -25,6 +25,8 @@ module ActiveSupport #:nodoc:
25
25
  def to_time(form = :local)
26
26
  ::Time.send(form, year, month, day)
27
27
  end
28
+
29
+ alias :xmlschema :to_s
28
30
  end
29
31
  end
30
32
  end
@@ -6,4 +6,26 @@ module Enumerable #:nodoc:
6
6
  end
7
7
  match
8
8
  end
9
- end
9
+
10
+ # Collect an enumerable into sets, grouped by the result of a block. Useful,
11
+ # for example, for grouping records by date.
12
+ #
13
+ # e.g.
14
+ #
15
+ # latest_transcripts.group_by(&:day).each do |day, transcripts|
16
+ # p "#{day} -> #{transcripts.map(&:class) * ', '}"
17
+ # end
18
+ # "2006-03-01 -> Transcript"
19
+ # "2006-02-28 -> Transcript"
20
+ # "2006-02-27 -> Transcript, Transcript"
21
+ # "2006-02-26 -> Transcript, Transcript"
22
+ # "2006-02-25 -> Transcript"
23
+ # "2006-02-24 -> Transcript, Transcript"
24
+ # "2006-02-23 -> Transcript"
25
+ def group_by
26
+ inject({}) do |groups, element|
27
+ (groups[yield(element)] ||= []) << element
28
+ groups
29
+ end
30
+ end
31
+ end
@@ -1,5 +1,4 @@
1
1
  class Exception
2
-
3
2
  alias :clean_message :message
4
3
 
5
4
  TraceSubstitutions = []
@@ -1,9 +1,13 @@
1
1
  require File.dirname(__FILE__) + '/hash/keys'
2
2
  require File.dirname(__FILE__) + '/hash/indifferent_access'
3
3
  require File.dirname(__FILE__) + '/hash/reverse_merge'
4
+ require File.dirname(__FILE__) + '/hash/conversions'
5
+ require File.dirname(__FILE__) + '/hash/diff'
4
6
 
5
7
  class Hash #:nodoc:
6
8
  include ActiveSupport::CoreExtensions::Hash::Keys
7
9
  include ActiveSupport::CoreExtensions::Hash::IndifferentAccess
8
10
  include ActiveSupport::CoreExtensions::Hash::ReverseMerge
11
+ include ActiveSupport::CoreExtensions::Hash::Conversions
12
+ include ActiveSupport::CoreExtensions::Hash::Diff
9
13
  end
@@ -0,0 +1,44 @@
1
+ module ActiveSupport #:nodoc:
2
+ module CoreExtensions #:nodoc:
3
+ module Hash #:nodoc:
4
+ module Conversions
5
+ XML_TYPE_NAMES = {
6
+ "Fixnum" => "integer",
7
+ "Date" => "date",
8
+ "Time" => "datetime",
9
+ "TrueClass" => "boolean",
10
+ "FalseClass" => "boolean"
11
+ }
12
+
13
+ XML_FORMATTING = {
14
+ "date" => Proc.new { |date| date.to_s(:db) },
15
+ "datetime" => Proc.new { |time| time.xmlschema }
16
+ }
17
+
18
+ def to_xml(options = {})
19
+ options[:indent] ||= 2
20
+ options.reverse_merge!({ :builder => Builder::XmlMarkup.new(:indent => options[:indent]), :root => "hash" })
21
+ options[:builder].instruct! unless options.delete(:skip_instruct)
22
+
23
+ options[:builder].__send__(options[:root].to_s.dasherize) do
24
+ each do |key, value|
25
+ case value
26
+ when ::Hash
27
+ value.to_xml(options.merge({ :root => key, :skip_instruct => true }))
28
+ when ::Array
29
+ value.to_xml(options.merge({ :root => key, :children => key.to_s.singularize, :skip_instruct => true}))
30
+ else
31
+ type_name = XML_TYPE_NAMES[value.class.to_s]
32
+
33
+ options[:builder].tag!(key.to_s.dasherize,
34
+ XML_FORMATTING[type_name] ? XML_FORMATTING[type_name].call(value) : value,
35
+ options[:skip_types] || value.nil? || type_name.nil? ? { } : { :type => type_name }
36
+ )
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,11 @@
1
+ module ActiveSupport #:nodoc:
2
+ module CoreExtensions #:nodoc:
3
+ module Hash #:nodoc:
4
+ module Diff
5
+ def diff(h2)
6
+ self.dup.delete_if { |k, v| h2[k] == v }.merge(h2.dup.delete_if { |k, v| self.has_key?(k) })
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,4 +1,6 @@
1
- # This implementation is HODEL-HASH-9600 compliant
1
+ # this class has dubious semantics and we only have it so that
2
+ # people can write params[:key] instead of params['key']
3
+
2
4
  class HashWithIndifferentAccess < Hash
3
5
  def initialize(constructor = {})
4
6
  if constructor.is_a?(Hash)
@@ -14,13 +16,18 @@ class HashWithIndifferentAccess < Hash
14
16
  end
15
17
 
16
18
  alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
19
+ alias_method :regular_update, :update unless method_defined?(:regular_update)
17
20
 
18
21
  def []=(key, value)
19
22
  regular_writer(convert_key(key), convert_value(value))
20
23
  end
21
- def update(hash)
22
- hash.each {|key, value| self[key] = value}
24
+
25
+ def update(other_hash)
26
+ other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
27
+ self
23
28
  end
29
+
30
+ alias_method :merge!, :update
24
31
 
25
32
  def key?(key)
26
33
  super(convert_key(key))
@@ -38,6 +45,18 @@ class HashWithIndifferentAccess < Hash
38
45
  indices.collect {|key| self[convert_key(key)]}
39
46
  end
40
47
 
48
+ def dup
49
+ HashWithIndifferentAccess.new(self)
50
+ end
51
+
52
+ def merge(hash)
53
+ self.dup.update(hash)
54
+ end
55
+
56
+ def delete(key)
57
+ super(convert_key(key))
58
+ end
59
+
41
60
  protected
42
61
  def convert_key(key)
43
62
  key.kind_of?(Symbol) ? key.to_s : key
@@ -57,4 +76,4 @@ module ActiveSupport #:nodoc:
57
76
  end
58
77
  end
59
78
  end
60
- end
79
+ end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../../inflector'
1
+ require File.dirname(__FILE__) + '/../../inflector' unless defined? Inflector
2
2
  module ActiveSupport #:nodoc:
3
3
  module CoreExtensions #:nodoc:
4
4
  module Integer #:nodoc:
@@ -1,79 +1,4 @@
1
- class Object
2
- # A Ruby-ized realization of the K combinator, courtesy of Mikael Brockman.
3
- #
4
- # def foo
5
- # returning values = [] do
6
- # values << 'bar'
7
- # values << 'baz'
8
- # end
9
- # end
10
- #
11
- # foo # => ['bar', 'baz']
12
- #
13
- def returning(value)
14
- yield
15
- value
16
- end
17
-
18
- # Sets $VERBOSE to nil for the duration of the block and back to its original value afterwards.
19
- #
20
- # silence_warnings do
21
- # value = noisy_call # no warning voiced
22
- # end
23
- #
24
- # noisy_call # warning voiced
25
- def silence_warnings
26
- old_verbose, $VERBOSE = $VERBOSE, nil
27
- yield
28
- ensure
29
- $VERBOSE = old_verbose
30
- end
31
-
32
- # Silences stderr for the duration of the block.
33
- #
34
- # silence_stderr do
35
- # $stderr.puts 'This will never be seen'
36
- # end
37
- #
38
- # $stderr.puts 'But this will'
39
- def silence_stderr
40
- old_stderr = STDERR.dup
41
- STDERR.reopen(RUBY_PLATFORM =~ /mswin/ ? 'NUL:' : '/dev/null')
42
- STDERR.sync = true
43
- yield
44
- ensure
45
- STDERR.reopen(old_stderr)
46
- end
47
-
48
- # Makes backticks behave (somewhat more) similarly on all platforms.
49
- # On win32 `nonexistent_command` raises Errno::ENOENT; on Unix, the
50
- # spawned shell prints a message to stderr and sets $?. We emulate
51
- # Unix on the former but not the latter.
52
- def `(command) #:nodoc:
53
- super
54
- rescue Errno::ENOENT => e
55
- STDERR.puts "#$0: #{e}"
56
- end
57
-
58
- # Method that requires a library, ensuring that rubygems is loaded
59
- def require_library_or_gem(library_name)
60
- begin
61
- require library_name
62
- rescue LoadError => cannot_require
63
- # 1. Requiring the module is unsuccessful, maybe it's a gem and nobody required rubygems yet. Try.
64
- begin
65
- require 'rubygems'
66
- rescue LoadError => rubygems_not_installed
67
- raise cannot_require
68
- end
69
- # 2. Rubygems is installed and loaded. Try to load the library again
70
- begin
71
- require library_name
72
- rescue LoadError => gem_not_installed
73
- raise cannot_require
74
- end
75
- end
76
- end
77
-
78
-
79
- end
1
+ require File.dirname(__FILE__) + '/kernel/daemonizing'
2
+ require File.dirname(__FILE__) + '/kernel/reporting'
3
+ require File.dirname(__FILE__) + '/kernel/agnostics'
4
+ require File.dirname(__FILE__) + '/kernel/requires'
@@ -0,0 +1,11 @@
1
+ class Object
2
+ # Makes backticks behave (somewhat more) similarly on all platforms.
3
+ # On win32 `nonexistent_command` raises Errno::ENOENT; on Unix, the
4
+ # spawned shell prints a message to stderr and sets $?. We emulate
5
+ # Unix on the former but not the latter.
6
+ def `(command) #:nodoc:
7
+ super
8
+ rescue Errno::ENOENT => e
9
+ STDERR.puts "#$0: #{e}"
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ module Kernel
2
+ # Turns the current script into a daemon process that detaches from the console.
3
+ # It can be shut down with a TERM signal.
4
+ def daemonize
5
+ exit if fork # Parent exits, child continues.
6
+ Process.setsid # Become session leader.
7
+ exit if fork # Zap session leader. See [1].
8
+ Dir.chdir "/" # Release old working directory.
9
+ File.umask 0000 # Ensure sensible umask. Adjust as needed.
10
+ STDIN.reopen "/dev/null" # Free file descriptors and
11
+ STDOUT.reopen "/dev/null", "a" # point them somewhere sensible.
12
+ STDERR.reopen STDOUT # STDOUT/ERR should better go to a logfile.
13
+ trap("TERM") { exit }
14
+ end
15
+ end
@@ -0,0 +1,51 @@
1
+ module Kernel
2
+ # Sets $VERBOSE to nil for the duration of the block and back to its original value afterwards.
3
+ #
4
+ # silence_warnings do
5
+ # value = noisy_call # no warning voiced
6
+ # end
7
+ #
8
+ # noisy_call # warning voiced
9
+ def silence_warnings
10
+ old_verbose, $VERBOSE = $VERBOSE, nil
11
+ yield
12
+ ensure
13
+ $VERBOSE = old_verbose
14
+ end
15
+
16
+ # Sets $VERBOSE to true for the duration of the block and back to its original value afterwards.
17
+ def enable_warnings
18
+ old_verbose, $VERBOSE = $VERBOSE, true
19
+ yield
20
+ ensure
21
+ $VERBOSE = old_verbose
22
+ end
23
+
24
+ # For compatibility
25
+ def silence_stderr #:nodoc:
26
+ silence_stream(STDERR) { yield }
27
+ end
28
+
29
+ # Silences any stream for the duration of the block.
30
+ #
31
+ # silence_stream(STDOUT) do
32
+ # puts 'This will never be seen'
33
+ # end
34
+ #
35
+ # puts 'But this will'
36
+ def silence_stream(stream)
37
+ old_stream = stream.dup
38
+ stream.reopen(RUBY_PLATFORM =~ /mswin/ ? 'NUL:' : '/dev/null')
39
+ stream.sync = true
40
+ yield
41
+ ensure
42
+ stream.reopen(old_stream)
43
+ end
44
+
45
+ def suppress(*exception_classes)
46
+ begin yield
47
+ rescue Exception => e
48
+ raise unless exception_classes.any? { |cls| e.kind_of?(cls) }
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,24 @@
1
+ module Kernel
2
+ # Require a library with fallback to RubyGems. Warnings during library
3
+ # loading are silenced to increase signal/noise for application warnings.
4
+ def require_library_or_gem(library_name)
5
+ silence_warnings do
6
+ begin
7
+ require library_name
8
+ rescue LoadError => cannot_require
9
+ # 1. Requiring the module is unsuccessful, maybe it's a gem and nobody required rubygems yet. Try.
10
+ begin
11
+ require 'rubygems'
12
+ rescue LoadError => rubygems_not_installed
13
+ raise cannot_require
14
+ end
15
+ # 2. Rubygems is installed and loaded. Try to load the library again
16
+ begin
17
+ require library_name
18
+ rescue LoadError => gem_not_installed
19
+ raise cannot_require
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,16 @@
1
+ # Adds the 'around_level' method to Logger.
2
+
3
+ class Logger
4
+ def self.define_around_helper(level)
5
+ module_eval <<-end_eval
6
+ def around_#{level}(before_message, after_message, &block)
7
+ self.#{level}(before_message)
8
+ return_value = block.call(self)
9
+ self.#{level}(after_message)
10
+ return return_value
11
+ end
12
+ end_eval
13
+ end
14
+ [:debug, :info, :error, :fatal].each {|level| define_around_helper(level) }
15
+
16
+ end
@@ -0,0 +1,5 @@
1
+ require File.dirname(__FILE__) + '/module/inclusion'
2
+ require File.dirname(__FILE__) + '/module/attribute_accessors'
3
+ require File.dirname(__FILE__) + '/module/delegation'
4
+ require File.dirname(__FILE__) + '/module/introspection'
5
+ require File.dirname(__FILE__) + '/module/loading'
@@ -0,0 +1,44 @@
1
+ # Extends the module object with module and instance accessors for class attributes,
2
+ # just like the native attr* accessors for instance attributes.
3
+ class Module # :nodoc:
4
+ def mattr_reader(*syms)
5
+ syms.each do |sym|
6
+ class_eval(<<-EOS, __FILE__, __LINE__)
7
+ unless defined? @@#{sym}
8
+ @@#{sym} = nil
9
+ end
10
+
11
+ def self.#{sym}
12
+ @@#{sym}
13
+ end
14
+
15
+ def #{sym}
16
+ @@#{sym}
17
+ end
18
+ EOS
19
+ end
20
+ end
21
+
22
+ def mattr_writer(*syms)
23
+ syms.each do |sym|
24
+ class_eval(<<-EOS, __FILE__, __LINE__)
25
+ unless defined? @@#{sym}
26
+ @@#{sym} = nil
27
+ end
28
+
29
+ def self.#{sym}=(obj)
30
+ @@#{sym} = obj
31
+ end
32
+
33
+ def #{sym}=(obj)
34
+ @@#{sym} = obj
35
+ end
36
+ EOS
37
+ end
38
+ end
39
+
40
+ def mattr_accessor(*syms)
41
+ mattr_reader(*syms)
42
+ mattr_writer(*syms)
43
+ end
44
+ end
@@ -0,0 +1,16 @@
1
+ class Module
2
+ def delegate(*methods)
3
+ options = methods.pop
4
+ unless options.is_a?(Hash) && to = options[:to]
5
+ raise ArgumentError, "Delegation needs a target. Supply an options hash with a :to key"
6
+ end
7
+
8
+ methods.each do |method|
9
+ module_eval(<<-EOS, "(__DELEGATION__)", 1)
10
+ def #{method}(*args, &block)
11
+ #{to}.__send__(#{method.inspect}, *args, &block)
12
+ end
13
+ EOS
14
+ end
15
+ end
16
+ end