activesupport 1.3.1 → 1.4.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 (55) hide show
  1. data/CHANGELOG +232 -2
  2. data/README +43 -0
  3. data/lib/active_support.rb +4 -1
  4. data/lib/active_support/breakpoint.rb +5 -0
  5. data/lib/active_support/core_ext/array.rb +2 -16
  6. data/lib/active_support/core_ext/array/conversions.rb +30 -4
  7. data/lib/active_support/core_ext/array/grouping.rb +55 -0
  8. data/lib/active_support/core_ext/bigdecimal.rb +3 -0
  9. data/lib/active_support/core_ext/bigdecimal/formatting.rb +7 -0
  10. data/lib/active_support/core_ext/class/inheritable_attributes.rb +6 -1
  11. data/lib/active_support/core_ext/date/conversions.rb +13 -7
  12. data/lib/active_support/core_ext/enumerable.rb +41 -10
  13. data/lib/active_support/core_ext/exception.rb +2 -2
  14. data/lib/active_support/core_ext/hash/conversions.rb +123 -12
  15. data/lib/active_support/core_ext/hash/indifferent_access.rb +18 -9
  16. data/lib/active_support/core_ext/integer/inflections.rb +10 -4
  17. data/lib/active_support/core_ext/load_error.rb +3 -3
  18. data/lib/active_support/core_ext/module.rb +2 -0
  19. data/lib/active_support/core_ext/module/aliasing.rb +58 -0
  20. data/lib/active_support/core_ext/module/attr_internal.rb +31 -0
  21. data/lib/active_support/core_ext/module/delegation.rb +27 -2
  22. data/lib/active_support/core_ext/name_error.rb +20 -0
  23. data/lib/active_support/core_ext/string.rb +2 -0
  24. data/lib/active_support/core_ext/string/access.rb +5 -5
  25. data/lib/active_support/core_ext/string/inflections.rb +93 -4
  26. data/lib/active_support/core_ext/string/unicode.rb +42 -0
  27. data/lib/active_support/core_ext/symbol.rb +1 -1
  28. data/lib/active_support/core_ext/time/calculations.rb +7 -5
  29. data/lib/active_support/core_ext/time/conversions.rb +1 -2
  30. data/lib/active_support/dependencies.rb +417 -50
  31. data/lib/active_support/deprecation.rb +201 -0
  32. data/lib/active_support/inflections.rb +1 -2
  33. data/lib/active_support/inflector.rb +117 -19
  34. data/lib/active_support/json.rb +14 -3
  35. data/lib/active_support/json/encoders/core.rb +21 -18
  36. data/lib/active_support/multibyte.rb +7 -0
  37. data/lib/active_support/multibyte/chars.rb +129 -0
  38. data/lib/active_support/multibyte/generators/generate_tables.rb +149 -0
  39. data/lib/active_support/multibyte/handlers/passthru_handler.rb +9 -0
  40. data/lib/active_support/multibyte/handlers/utf8_handler.rb +453 -0
  41. data/lib/active_support/multibyte/handlers/utf8_handler_proc.rb +44 -0
  42. data/lib/active_support/option_merger.rb +3 -3
  43. data/lib/active_support/ordered_options.rb +24 -23
  44. data/lib/active_support/reloadable.rb +39 -5
  45. data/lib/active_support/values/time_zone.rb +1 -1
  46. data/lib/active_support/values/unicode_tables.dat +0 -0
  47. data/lib/active_support/vendor/builder/blankslate.rb +16 -6
  48. data/lib/active_support/vendor/builder/xchar.rb +112 -0
  49. data/lib/active_support/vendor/builder/xmlbase.rb +12 -10
  50. data/lib/active_support/vendor/builder/xmlmarkup.rb +26 -7
  51. data/lib/active_support/vendor/xml_simple.rb +1021 -0
  52. data/lib/active_support/version.rb +2 -2
  53. data/lib/active_support/whiny_nil.rb +1 -1
  54. metadata +26 -4
  55. data/lib/active_support/core_ext/hash/conversions.rb.rej +0 -28
@@ -0,0 +1,44 @@
1
+ # Methods in this handler call functions in the utf8proc ruby extension. These are significantly faster than the
2
+ # pure ruby versions. Chars automatically uses this handler when it can load the utf8proc extension. For
3
+ # documentation on handler methods see UTF8Handler.
4
+ class ActiveSupport::Multibyte::Handlers::UTF8HandlerProc < ActiveSupport::Multibyte::Handlers::UTF8Handler
5
+
6
+ class << self
7
+ def normalize(str, form=ActiveSupport::Multibyte::DEFAULT_NORMALIZATION_FORM) #:nodoc:
8
+ codepoints = str.unpack('U*')
9
+ case form
10
+ when :d
11
+ utf8map(str, :stable)
12
+ when :c
13
+ utf8map(str, :stable, :compose)
14
+ when :kd
15
+ utf8map(str, :stable, :compat)
16
+ when :kc
17
+ utf8map(str, :stable, :compose, :compat)
18
+ else
19
+ raise ArgumentError, "#{form} is not a valid normalization variant", caller
20
+ end
21
+ end
22
+
23
+ def decompose(str) #:nodoc:
24
+ utf8map(str, :stable)
25
+ end
26
+
27
+ def downcase(str) #:nodoc:c
28
+ utf8map(str, :casefold)
29
+ end
30
+
31
+ protected
32
+
33
+ def utf8map(str, *option_array) #:nodoc:
34
+ options = 0
35
+ option_array.each do |option|
36
+ flag = Utf8Proc::Options[option]
37
+ raise ArgumentError, "Unknown argument given to utf8map." unless
38
+ flag
39
+ options |= flag
40
+ end
41
+ return Utf8Proc::utf8map(str, options)
42
+ end
43
+ end
44
+ end
@@ -1,7 +1,7 @@
1
1
  module ActiveSupport
2
2
  class OptionMerger #:nodoc:
3
3
  instance_methods.each do |method|
4
- undef_method(method) if method !~ /^(__|instance_eval)/
4
+ undef_method(method) if method !~ /^(__|instance_eval|class)/
5
5
  end
6
6
 
7
7
  def initialize(context, options)
@@ -15,8 +15,8 @@ module ActiveSupport
15
15
  end
16
16
 
17
17
  def merge_argument_options!(arguments)
18
- arguments << if arguments.last.respond_to? :merge!
19
- arguments.pop.dup.merge!(@options)
18
+ arguments << if arguments.last.respond_to? :to_hash
19
+ @options.merge(arguments.pop)
20
20
  else
21
21
  @options.dup
22
22
  end
@@ -1,34 +1,35 @@
1
- class OrderedHash < Array #:nodoc:
2
- def []=(key, value)
3
- if pair = find_pair(key)
4
- pair.pop
5
- pair << value
6
- else
7
- self << [key, value]
1
+ # OrderedHash is namespaced to prevent conflicts with other implementations
2
+ module ActiveSupport
3
+ class OrderedHash < Array #:nodoc:
4
+ def []=(key, value)
5
+ if pair = assoc(key)
6
+ pair.pop
7
+ pair << value
8
+ else
9
+ self << [key, value]
10
+ end
8
11
  end
9
- end
10
-
11
- def [](key)
12
- pair = find_pair(key)
13
- pair ? pair.last : nil
14
- end
15
12
 
16
- def keys
17
- self.collect { |i| i.first }
18
- end
13
+ def [](key)
14
+ pair = assoc(key)
15
+ pair ? pair.last : nil
16
+ end
19
17
 
20
- private
21
- def find_pair(key)
22
- self.each { |i| return i if i.first == key }
23
- return false
18
+ def keys
19
+ collect { |key, value| key }
24
20
  end
21
+
22
+ def values
23
+ collect { |key, value| value }
24
+ end
25
+ end
25
26
  end
26
27
 
27
- class OrderedOptions < OrderedHash #:nodoc:
28
+ class OrderedOptions < ActiveSupport::OrderedHash #:nodoc:
28
29
  def []=(key, value)
29
30
  super(key.to_sym, value)
30
31
  end
31
-
32
+
32
33
  def [](key)
33
34
  super(key.to_sym)
34
35
  end
@@ -40,4 +41,4 @@ class OrderedOptions < OrderedHash #:nodoc:
40
41
  self[name]
41
42
  end
42
43
  end
43
- end
44
+ end
@@ -1,30 +1,64 @@
1
- # Classes that include this module will automatically be reloaded
2
- # by the Rails dispatcher when Dependencies.mechanism = :load.
1
+ require 'active_support/deprecation'
2
+
3
+ # A deprecated mechanism to mark a class reloadable.
4
+ #
5
+ # Deprecated as of Rails 1.2.
6
+ # All autoloaded objects are now unloaded.
3
7
  module Reloadable
4
8
  class << self
9
+
5
10
  def included(base) #nodoc:
11
+ unless base.ancestors.include?(Reloadable::Subclasses) # Avoid double warning
12
+ ActiveSupport::Deprecation.warn "Reloadable has been deprecated and has no effect.", caller
13
+ end
14
+
6
15
  raise TypeError, "Only Classes can be Reloadable!" unless base.is_a? Class
7
16
 
8
17
  unless base.respond_to?(:reloadable?)
9
18
  class << base
10
- define_method(:reloadable?) { true }
19
+ define_method(:reloadable?) do
20
+ ActiveSupport::Deprecation.warn "Reloadable has been deprecated and reloadable? has no effect", caller
21
+ true
22
+ end
11
23
  end
12
24
  end
13
25
  end
14
26
 
15
27
  def reloadable_classes
16
- included_in_classes.select { |klass| klass.reloadable? }
28
+ ActiveSupport::Deprecation.silence do
29
+ included_in_classes.select { |klass| klass.reloadable? }
30
+ end
17
31
  end
32
+ deprecate :reloadable_classes
18
33
  end
19
34
 
20
35
  # Captures the common pattern where a base class should not be reloaded,
21
36
  # but its subclasses should be.
37
+ #
38
+ # Deprecated as of Rails 1.2.
39
+ # All autoloaded objects are now unloaded.
22
40
  module Subclasses
23
41
  def self.included(base) #nodoc:
24
42
  base.send :include, Reloadable
43
+ ActiveSupport::Deprecation.warn "Reloadable::Subclasses has been deprecated and has no effect.", caller
25
44
  (class << base; self; end).send(:define_method, :reloadable?) do
26
- base != self
45
+ ActiveSupport::Deprecation.warn "Reloadable has been deprecated and reloadable? has no effect", caller
46
+ base != self
47
+ end
48
+ end
49
+ end
50
+
51
+ module Deprecated
52
+
53
+ def self.included(base)
54
+ class << base
55
+ define_method(:reloadable?) do
56
+ ActiveSupport::Deprecation.warn "Reloadable has been deprecated and reloadable? has no effect", caller
57
+ true # This might not have the desired effect, as AR::B.reloadable? => true.
58
+ end
27
59
  end
28
60
  end
61
+
29
62
  end
63
+
30
64
  end
@@ -169,7 +169,7 @@ class TimeZone
169
169
 
170
170
  # A regular expression that matches the names of all time zones in
171
171
  # the USA.
172
- US_ZONES = /US|Arizona|Indiana|Hawaii|Alaska/
172
+ US_ZONES = /US|Arizona|Indiana|Hawaii|Alaska/ unless defined?(US_ZONES)
173
173
 
174
174
  # A convenience method for returning a collection of TimeZone objects
175
175
  # for time zones in the USA.
@@ -14,12 +14,15 @@ module Builder #:nodoc:
14
14
  # methods (except for <tt>\_\_send__</tt> and <tt>\_\_id__</tt>).
15
15
  # BlankSlate is useful as a base class when writing classes that
16
16
  # depend upon <tt>method_missing</tt> (e.g. dynamic proxies).
17
- class BlankSlate #:nodoc:
17
+ class BlankSlate
18
18
  class << self
19
+
20
+ # Hide the method named +name+ in the BlankSlate class. Don't
21
+ # hide +instance_eval+ or any method beginning with "__".
19
22
  def hide(name)
20
- undef_method name if
21
- instance_methods.include?(name.to_s) and
22
- name !~ /^(__|instance_eval)/
23
+ undef_method name if
24
+ instance_methods.include?(name.to_s) and
25
+ name !~ /^(__|instance_eval)/
23
26
  end
24
27
  end
25
28
 
@@ -29,10 +32,14 @@ end
29
32
 
30
33
  # Since Ruby is very dynamic, methods added to the ancestors of
31
34
  # BlankSlate <em>after BlankSlate is defined</em> will show up in the
32
- # list of available BlankSlate methods. We handle this by defining a hook in the Object and Kernel classes that will hide any defined
35
+ # list of available BlankSlate methods. We handle this by defining a
36
+ # hook in the Object and Kernel classes that will hide any defined
33
37
  module Kernel #:nodoc:
34
38
  class << self
35
39
  alias_method :blank_slate_method_added, :method_added
40
+
41
+ # Detect method additions to Kernel and remove them in the
42
+ # BlankSlate class.
36
43
  def method_added(name)
37
44
  blank_slate_method_added(name)
38
45
  return if self != Kernel
@@ -44,9 +51,12 @@ end
44
51
  class Object #:nodoc:
45
52
  class << self
46
53
  alias_method :blank_slate_method_added, :method_added
54
+
55
+ # Detect method additions to Object and remove them in the
56
+ # BlankSlate class.
47
57
  def method_added(name)
48
58
  blank_slate_method_added(name)
49
- return if self != Object
59
+ return if self != Object
50
60
  Builder::BlankSlate.hide(name)
51
61
  end
52
62
  end
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # The XChar library is provided courtesy of Sam Ruby (See
4
+ # http://intertwingly.net/stories/2005/09/28/xchar.rb)
5
+
6
+ # --------------------------------------------------------------------
7
+
8
+ # If the Builder::XChar module is not currently defined, fail on any
9
+ # name clashes in standard library classes.
10
+
11
+ module Builder
12
+ def self.check_for_name_collision(klass, method_name, defined_constant=nil)
13
+ if klass.instance_methods.include?(method_name)
14
+ fail RuntimeError,
15
+ "Name Collision: Method '#{method_name}' is already defined in #{klass}"
16
+ end
17
+ end
18
+ end
19
+
20
+ if ! defined?(Builder::XChar)
21
+ Builder.check_for_name_collision(String, "to_xs")
22
+ Builder.check_for_name_collision(Fixnum, "xchr")
23
+ end
24
+
25
+ ######################################################################
26
+ module Builder
27
+
28
+ ####################################################################
29
+ # XML Character converter, from Sam Ruby:
30
+ # (see http://intertwingly.net/stories/2005/09/28/xchar.rb).
31
+ #
32
+ module XChar # :nodoc:
33
+
34
+ # See
35
+ # http://intertwingly.net/stories/2004/04/14/i18n.html#CleaningWindows
36
+ # for details.
37
+ CP1252 = { # :nodoc:
38
+ 128 => 8364, # euro sign
39
+ 130 => 8218, # single low-9 quotation mark
40
+ 131 => 402, # latin small letter f with hook
41
+ 132 => 8222, # double low-9 quotation mark
42
+ 133 => 8230, # horizontal ellipsis
43
+ 134 => 8224, # dagger
44
+ 135 => 8225, # double dagger
45
+ 136 => 710, # modifier letter circumflex accent
46
+ 137 => 8240, # per mille sign
47
+ 138 => 352, # latin capital letter s with caron
48
+ 139 => 8249, # single left-pointing angle quotation mark
49
+ 140 => 338, # latin capital ligature oe
50
+ 142 => 381, # latin capital letter z with caron
51
+ 145 => 8216, # left single quotation mark
52
+ 146 => 8217, # right single quotation mark
53
+ 147 => 8220, # left double quotation mark
54
+ 148 => 8221, # right double quotation mark
55
+ 149 => 8226, # bullet
56
+ 150 => 8211, # en dash
57
+ 151 => 8212, # em dash
58
+ 152 => 732, # small tilde
59
+ 153 => 8482, # trade mark sign
60
+ 154 => 353, # latin small letter s with caron
61
+ 155 => 8250, # single right-pointing angle quotation mark
62
+ 156 => 339, # latin small ligature oe
63
+ 158 => 382, # latin small letter z with caron
64
+ 159 => 376, # latin capital letter y with diaeresis
65
+ }
66
+
67
+ # See http://www.w3.org/TR/REC-xml/#dt-chardata for details.
68
+ PREDEFINED = {
69
+ 38 => '&amp;', # ampersand
70
+ 60 => '&lt;', # left angle bracket
71
+ 62 => '&gt;', # right angle bracket
72
+ }
73
+
74
+ # See http://www.w3.org/TR/REC-xml/#charsets for details.
75
+ VALID = [
76
+ [0x9, 0xA, 0xD],
77
+ (0x20..0xD7FF),
78
+ (0xE000..0xFFFD),
79
+ (0x10000..0x10FFFF)
80
+ ]
81
+ end
82
+
83
+ end
84
+
85
+
86
+ ######################################################################
87
+ # Enhance the Fixnum class with a XML escaped character conversion.
88
+ #
89
+ class Fixnum #:nodoc:
90
+ XChar = Builder::XChar if ! defined?(XChar)
91
+
92
+ # XML escaped version of chr
93
+ def xchr
94
+ n = XChar::CP1252[self] || self
95
+ n = 42 unless XChar::VALID.find {|range| range.include? n}
96
+ XChar::PREDEFINED[n] or (n<128 ? n.chr : "&##{n};")
97
+ end
98
+ end
99
+
100
+
101
+ ######################################################################
102
+ # Enhance the String class with a XML escaped character version of
103
+ # to_s.
104
+ #
105
+ class String #:nodoc:
106
+ # XML escaped version of to_s
107
+ def to_xs
108
+ unpack('U*').map {|n| n.xchr}.join # ASCII, UTF-8
109
+ rescue
110
+ unpack('C*').map {|n| n.xchr}.join # ISO-8859-1, WIN-1252
111
+ end
112
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'builder/blankslate'
4
4
 
5
- module Builder #:nodoc:
5
+ module Builder
6
6
 
7
7
  # Generic error for builder
8
8
  class IllegalBlockError < RuntimeError #:nodoc:
@@ -14,7 +14,7 @@ module Builder #:nodoc:
14
14
 
15
15
  # Create an XML markup builder.
16
16
  #
17
- # out:: Object receiving the markup.1 +out+ must respond to
17
+ # out:: Object receiving the markup. +out+ must respond to
18
18
  # <tt><<</tt>.
19
19
  # indent:: Number of spaces used for indentation (0 implies no
20
20
  # indentation and no line breaks).
@@ -53,7 +53,7 @@ module Builder #:nodoc:
53
53
  unless text.nil?
54
54
  raise ArgumentError, "XmlMarkup cannot mix a text argument with a block"
55
55
  end
56
- _capture_outer_self(block) if @self.nil?
56
+ _capture_outer_self(block) unless defined?(@self) && !@self.nil?
57
57
  _indent
58
58
  _start_tag(sym, attrs)
59
59
  _newline
@@ -76,15 +76,15 @@ module Builder #:nodoc:
76
76
  end
77
77
 
78
78
  # Append text to the output target. Escape any markup. May be
79
- # used within the markup brackets as:
79
+ # used within the markup brakets as:
80
80
  #
81
- # builder.p { br; text! "HI" } #=> <p><br/>HI</p>
81
+ # builder.p { |b| b.br; b.text! "HI" } #=> <p><br/>HI</p>
82
82
  def text!(text)
83
83
  _text(_escape(text))
84
84
  end
85
85
 
86
86
  # Append text to the output target without escaping any markup.
87
- # May be used within the markup brackets as:
87
+ # May be used within the markup brakets as:
88
88
  #
89
89
  # builder.p { |x| x << "<br/>HI" } #=> <p><br/>HI</p>
90
90
  #
@@ -112,11 +112,13 @@ module Builder #:nodoc:
112
112
 
113
113
  private
114
114
 
115
+ require 'builder/xchar'
115
116
  def _escape(text)
116
- text.
117
- gsub(%r{&}, '&amp;').
118
- gsub(%r{<}, '&lt;').
119
- gsub(%r{>}, '&gt;')
117
+ text.to_xs
118
+ end
119
+
120
+ def _escape_quote(text)
121
+ _escape(text).gsub(%r{"}, '&quot;') # " WART
120
122
  end
121
123
 
122
124
  def _capture_outer_self(block)
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  #--
3
- # Copyright 2004 by Jim Weirich (jim@weirichhouse.org).
3
+ # Copyright 2004, 2005 by Jim Weirich (jim@weirichhouse.org).
4
4
  # All rights reserved.
5
5
 
6
6
  # Permission is granted for use, copying, modification, distribution,
@@ -38,7 +38,6 @@ module Builder
38
38
  # xm.title("History") # <title>History</title>
39
39
  # } # </head>
40
40
  # xm.body { # <body>
41
- # xm.comment! "HI" # <!-- HI -->
42
41
  # xm.h1("Header") # <h1>Header</h1>
43
42
  # xm.p("paragraph") # <p>paragraph</p>
44
43
  # } # </body>
@@ -165,13 +164,23 @@ module Builder
165
164
  # :target=><em>target_object</em>::
166
165
  # Object receiving the markup. +out+ must respond to the
167
166
  # <tt><<</tt> operator. The default is a plain string target.
167
+ #
168
168
  # :indent=><em>indentation</em>::
169
169
  # Number of spaces used for indentation. The default is no
170
170
  # indentation and no line breaks.
171
+ #
171
172
  # :margin=><em>initial_indentation_level</em>::
172
173
  # Amount of initial indentation (specified in levels, not
173
174
  # spaces).
174
175
  #
176
+ # :escape_attrs=><b>OBSOLETE</em>::
177
+ # The :escape_attrs option is no longer supported by builder
178
+ # (and will be quietly ignored). String attribute values are
179
+ # now automatically escaped. If you need unescaped attribute
180
+ # values (perhaps you are using entities in the attribute
181
+ # values), then give the value as a Symbol. This allows much
182
+ # finer control over escaping attribute values.
183
+ #
175
184
  def initialize(options={})
176
185
  indent = options[:indent] || 0
177
186
  margin = options[:margin] || 0
@@ -239,12 +248,13 @@ module Builder
239
248
  [:version, :encoding, :standalone])
240
249
  end
241
250
 
242
- # Surrounds the given text with a CDATA tag
251
+ # Insert a CDATA section into the XML markup.
243
252
  #
244
253
  # For example:
245
254
  #
246
- # xml.cdata! "blah blah blah"
247
- # # => <![CDATA[blah blah blah]]>
255
+ # xml.cdata!("text to be included in cdata")
256
+ # #=> <![CDATA[text to be included in cdata]]>
257
+ #
248
258
  def cdata!(text)
249
259
  _ensure_no_block block_given?
250
260
  _special("<![CDATA[", "]]>", text, nil)
@@ -289,10 +299,19 @@ module Builder
289
299
  return if attrs.nil?
290
300
  order.each do |k|
291
301
  v = attrs[k]
292
- @target << %{ #{k}="#{v}"} if v
302
+ @target << %{ #{k}="#{_attr_value(v)}"} if v
293
303
  end
294
304
  attrs.each do |k, v|
295
- @target << %{ #{k}="#{v}"} unless order.member?(k)
305
+ @target << %{ #{k}="#{_attr_value(v)}"} unless order.member?(k)
306
+ end
307
+ end
308
+
309
+ def _attr_value(value)
310
+ case value
311
+ when Symbol
312
+ value.to_s
313
+ else
314
+ _escape_quote(value.to_s)
296
315
  end
297
316
  end
298
317