activesupport 1.0.4 → 1.1.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.
- data/CHANGELOG +42 -5
- data/lib/active_support/class_attribute_accessors.rb +3 -3
- data/lib/active_support/clean_logger.rb +8 -0
- data/lib/active_support/core_ext/array.rb +5 -0
- data/lib/active_support/core_ext/array/to_param.rb +12 -0
- data/lib/active_support/core_ext/cgi.rb +5 -0
- data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +14 -0
- data/lib/active_support/core_ext/date/conversions.rb +6 -5
- data/lib/active_support/core_ext/fixnum.rb +4 -0
- data/lib/active_support/core_ext/fixnum/even_odd.rb +5 -1
- data/lib/active_support/core_ext/hash/indifferent_access.rb +6 -12
- data/lib/active_support/core_ext/load_error.rb +5 -5
- data/lib/active_support/core_ext/numeric/time.rb +2 -2
- data/lib/active_support/core_ext/object_and_class.rb +12 -2
- data/lib/active_support/core_ext/time/calculations.rb +7 -5
- data/lib/active_support/core_ext/time/conversions.rb +7 -6
- data/lib/active_support/dependencies.rb +45 -43
- data/lib/active_support/inflector.rb +48 -20
- data/lib/active_support/whiny_nil.rb +46 -0
- metadata +10 -3
data/CHANGELOG
CHANGED
@@ -1,3 +1,40 @@
|
|
1
|
+
*SVN*
|
2
|
+
|
3
|
+
* Fixed conflict with Glue gem #1606 [Rick Olson]
|
4
|
+
|
5
|
+
* Added new rules to the Inflector to deal with more unusual plurals mouse/louse => mice/lice, information => information, ox => oxen, virus => viri, archive => archives #1571, #1583, #1490, #1599, #1608 [foamdino@gmail.com/others]
|
6
|
+
|
7
|
+
* Fixed memory leak with Object#remove_subclasses_of, which inflicted a Rails application running in development mode with a ~20KB leak per request #1289 [c.r.mcgrath@gmail.com]
|
8
|
+
|
9
|
+
* Made 1.year == 365.25.days to account for leap years. This allows you to do User.find(:all, :conditions => ['birthday > ?', 50.years.ago]) without losing a lot of days. #1488 [tuxie@dekadance.se]
|
10
|
+
|
11
|
+
* Added an exception if calling id on nil to WhinyNil #584 [kevin-temp@writesoon.com]
|
12
|
+
|
13
|
+
* Added Fix/Bignum#multiple_of? which returns true on 14.multiple_of?(7) and false on 16.multiple_of?(7) #1464 [Thomas Fuchs]
|
14
|
+
|
15
|
+
* Added even? and odd? to work with Bignums in addition to Fixnums #1464 [Thomas Fuchs]
|
16
|
+
|
17
|
+
* Fixed Time#at_beginning_of_week returned the next Monday instead of the previous one when called on a Sunday #1403 [jean.helou@gmail.com]
|
18
|
+
|
19
|
+
* Increased the speed of indifferent hash access by using Hash#default. #1436 [Nicholas Seckar]
|
20
|
+
|
21
|
+
* Added that " " is now also blank? (using strip if available)
|
22
|
+
|
23
|
+
* Fixed Dependencies so all modules are able to load missing constants #1173 [Nicholas Seckar]
|
24
|
+
|
25
|
+
* Fixed the Inflector to underscore strings containing numbers, so Area51Controller becomes area51_controller #1176 [Nicholas Seckar]
|
26
|
+
|
27
|
+
* Fixed that HashWithIndifferentAccess stringified all keys including symbols, ints, objects, and arrays #1162 [Nicholas Seckar]
|
28
|
+
|
29
|
+
* Fixed Time#last_year to go back in time, not forward #1278 [fabien@odilat.com]
|
30
|
+
|
31
|
+
* Fixed the pluralization of analysis to analyses #1295 [seattle@rootimage.msu.edu]
|
32
|
+
|
33
|
+
* Fixed that Time.local(2005,12).months_since(1) would raise "ArgumentError: argument out of range" #1311 [jhahn@niveon.com]
|
34
|
+
|
35
|
+
* Added silencing to the default Logger class
|
36
|
+
|
37
|
+
|
1
38
|
*1.0.4* (19th April, 2005)
|
2
39
|
|
3
40
|
* Fixed that in some circumstances controllers outside of modules may have hidden ones inside modules. For example, admin/content might have been hidden by /content. #1075 [Nicholas Seckar]
|
@@ -11,7 +48,7 @@
|
|
11
48
|
|
12
49
|
*1.0.3* (27th March, 2005)
|
13
50
|
|
14
|
-
* Fixed Inflector.pluralize to handle capitalized words #932 [
|
51
|
+
* Fixed Inflector.pluralize to handle capitalized words #932 [Jeremy Kemper]
|
15
52
|
|
16
53
|
* Added Object#suppress which allows you to make a saner choice around with exceptions to swallow #980. Example:
|
17
54
|
|
@@ -90,7 +127,7 @@
|
|
90
127
|
|
91
128
|
* Added Inflector.humanize to turn attribute names like employee_salary into "Employee salary". Used by automated error reporting in AR.
|
92
129
|
|
93
|
-
* Added availability of class inheritable attributes to the masses #477 [
|
130
|
+
* Added availability of class inheritable attributes to the masses #477 [Jeremy Kemper]
|
94
131
|
|
95
132
|
class Foo
|
96
133
|
class_inheritable_reader :read_me
|
@@ -108,14 +145,14 @@
|
|
108
145
|
Bar.read_and_write_me = 'bar'
|
109
146
|
Bar.read_and_write_me != Foo.read_and_write_me
|
110
147
|
|
111
|
-
* Added Inflections as an extension on String, so Inflector.pluralize(Inflector.classify(name)) becomes name.classify.pluralize #476 [
|
148
|
+
* Added Inflections as an extension on String, so Inflector.pluralize(Inflector.classify(name)) becomes name.classify.pluralize #476 [Jeremy Kemper]
|
112
149
|
|
113
150
|
* Added Byte operations to Numeric, so 5.5.megabytes + 200.kilobytes #461 [Marcel Molina]
|
114
151
|
|
115
152
|
* Fixed that Dependencies.reload can't load the same file twice #420 [Kent Sibilev]
|
116
153
|
|
117
|
-
* Added Fixnum#ago/until, Fixnum#since/from_now #450 [
|
154
|
+
* Added Fixnum#ago/until, Fixnum#since/from_now #450 [Jeremy Kemper]
|
118
155
|
|
119
156
|
* Added that Inflector now accepts Symbols and Classes by calling .to_s on the word supplied
|
120
157
|
|
121
|
-
* Added time unit extensions to Fixnum that'll return the period in seconds, like 2.days + 4.hours.
|
158
|
+
* Added time unit extensions to Fixnum that'll return the period in seconds, like 2.days + 4.hours.
|
@@ -2,7 +2,7 @@
|
|
2
2
|
# just like the native attr* accessors for instance attributes.
|
3
3
|
class Class # :nodoc:
|
4
4
|
def cattr_reader(*syms)
|
5
|
-
syms.each do |sym|
|
5
|
+
syms.select { |sym| sym.respond_to?(:id2name) }.each do |sym|
|
6
6
|
class_eval <<-EOS
|
7
7
|
if ! defined? @@#{sym.id2name}
|
8
8
|
@@#{sym.id2name} = nil
|
@@ -29,7 +29,7 @@ class Class # :nodoc:
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def cattr_writer(*syms)
|
32
|
-
syms.each do |sym|
|
32
|
+
syms.select { |sym| sym.respond_to?(:id2name) }.each do |sym|
|
33
33
|
class_eval <<-EOS
|
34
34
|
if ! defined? @@#{sym.id2name}
|
35
35
|
@@#{sym.id2name} = nil
|
@@ -54,4 +54,4 @@ class Class # :nodoc:
|
|
54
54
|
cattr_reader(*syms)
|
55
55
|
cattr_writer(*syms)
|
56
56
|
end
|
57
|
-
end
|
57
|
+
end
|
@@ -1,6 +1,14 @@
|
|
1
1
|
require 'logger'
|
2
2
|
|
3
3
|
class Logger #:nodoc:
|
4
|
+
# Silences the logger for the duration of the block.
|
5
|
+
def silence(temporary_level = Logger::ERROR)
|
6
|
+
old_logger_level, self.level = level, temporary_level
|
7
|
+
yield
|
8
|
+
ensure
|
9
|
+
self.level = old_logger_level
|
10
|
+
end
|
11
|
+
|
4
12
|
private
|
5
13
|
remove_const "Format"
|
6
14
|
Format = "%s\n"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module ActiveSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module CGI #:nodoc:
|
4
|
+
module EscapeSkippingSlashes #:nodoc:
|
5
|
+
def escape_skipping_slashes(str)
|
6
|
+
str = str.join('/') if str.respond_to? :join
|
7
|
+
str.gsub(/([^ \/a-zA-Z0-9_.-])/n) do
|
8
|
+
"%#{$1.unpack('H2').first.upcase}"
|
9
|
+
end.tr(' ', '+')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -3,6 +3,11 @@ module ActiveSupport #:nodoc:
|
|
3
3
|
module Date #:nodoc:
|
4
4
|
# Getting dates in different convenient string representations and other objects
|
5
5
|
module Conversions
|
6
|
+
DATE_FORMATS = {
|
7
|
+
:short => "%e %b",
|
8
|
+
:long => "%B %e, %Y"
|
9
|
+
}
|
10
|
+
|
6
11
|
def self.append_features(klass) #:nodoc:
|
7
12
|
super
|
8
13
|
klass.send(:alias_method, :to_default_s, :to_s)
|
@@ -10,11 +15,7 @@ module ActiveSupport #:nodoc:
|
|
10
15
|
end
|
11
16
|
|
12
17
|
def to_formatted_s(format = :default)
|
13
|
-
|
14
|
-
when :default then to_default_s
|
15
|
-
when :short then strftime("%e %b").strip
|
16
|
-
when :long then strftime("%B %e, %Y").strip
|
17
|
-
end
|
18
|
+
DATE_FORMATS[format] ? strftime(DATE_FORMATS[format]).strip : to_default_s
|
18
19
|
end
|
19
20
|
|
20
21
|
# To be able to keep Dates and Times interchangeable on conversions
|
@@ -3,21 +3,15 @@ class HashWithIndifferentAccess < Hash
|
|
3
3
|
def initialize(constructor = {})
|
4
4
|
if constructor.is_a?(Hash)
|
5
5
|
super()
|
6
|
-
update(constructor
|
6
|
+
update(constructor)
|
7
7
|
else
|
8
8
|
super(constructor)
|
9
9
|
end
|
10
10
|
end
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
case key
|
16
|
-
when Symbol: regular_reader(key.to_s) || regular_reader(key)
|
17
|
-
when String: regular_reader(key) || regular_reader(key.to_sym)
|
18
|
-
else regular_reader(key)
|
19
|
-
end
|
20
|
-
end
|
11
|
+
|
12
|
+
def default(key)
|
13
|
+
self[key.to_s] if key.is_a?(Symbol)
|
14
|
+
end
|
21
15
|
|
22
16
|
alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
|
23
17
|
|
@@ -56,7 +50,7 @@ end
|
|
56
50
|
module ActiveSupport #:nodoc:
|
57
51
|
module CoreExtensions #:nodoc:
|
58
52
|
module Hash #:nodoc:
|
59
|
-
module IndifferentAccess
|
53
|
+
module IndifferentAccess #:nodoc:
|
60
54
|
def with_indifferent_access
|
61
55
|
HashWithIndifferentAccess.new(self)
|
62
56
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class MissingSourceFile < LoadError
|
1
|
+
class MissingSourceFile < LoadError #:nodoc:
|
2
2
|
attr_reader :path
|
3
3
|
def initialize(message, path)
|
4
4
|
super(message)
|
@@ -24,10 +24,10 @@ class MissingSourceFile < LoadError
|
|
24
24
|
]
|
25
25
|
end
|
26
26
|
|
27
|
-
module ActiveSupport
|
28
|
-
module CoreExtensions
|
29
|
-
module LoadErrorExtensions
|
30
|
-
module LoadErrorClassMethods
|
27
|
+
module ActiveSupport #:nodoc:
|
28
|
+
module CoreExtensions #:nodoc:
|
29
|
+
module LoadErrorExtensions #:nodoc:
|
30
|
+
module LoadErrorClassMethods #:nodoc:
|
31
31
|
def new(*args)
|
32
32
|
(self == LoadError && MissingSourceFile.from_message(args.first)) || super
|
33
33
|
end
|
@@ -1,6 +1,13 @@
|
|
1
1
|
class Object #:nodoc:
|
2
2
|
def remove_subclasses_of(superclass)
|
3
|
-
subclasses_of(superclass).each
|
3
|
+
subclasses_of(superclass).each do |subclass|
|
4
|
+
ObjectSpace.each_object(Class) do |k|
|
5
|
+
if k.to_s == subclass
|
6
|
+
k.instance_variables.each { |v| k.send(:remove_instance_variable, v) }
|
7
|
+
end
|
8
|
+
end
|
9
|
+
Object.send(:remove_const, subclass) rescue nil
|
10
|
+
end
|
4
11
|
end
|
5
12
|
|
6
13
|
def subclasses_of(superclass)
|
@@ -12,8 +19,11 @@ class Object #:nodoc:
|
|
12
19
|
subclasses
|
13
20
|
end
|
14
21
|
|
22
|
+
# "", " ", nil, and 0 are all blank
|
15
23
|
def blank?
|
16
|
-
if respond_to?
|
24
|
+
if respond_to?(:empty?) && respond_to?(:strip)
|
25
|
+
strip.empty?
|
26
|
+
elsif respond_to? :empty?
|
17
27
|
empty?
|
18
28
|
elsif respond_to? :zero?
|
19
29
|
zero?
|
@@ -48,7 +48,8 @@ module ActiveSupport #:nodoc:
|
|
48
48
|
|
49
49
|
def months_since(months)
|
50
50
|
if months + self.month > 12
|
51
|
-
|
51
|
+
old_time = self
|
52
|
+
change(:year => self.year + 1, :month => 1).months_since(months + old_time.month - 12 - 1)
|
52
53
|
else
|
53
54
|
change(:year => self.year, :month => self.month + months)
|
54
55
|
end
|
@@ -63,12 +64,12 @@ module ActiveSupport #:nodoc:
|
|
63
64
|
change(:year => self.year + years)
|
64
65
|
end
|
65
66
|
|
66
|
-
# Short-hand for
|
67
|
+
# Short-hand for years_ago(1)
|
67
68
|
def last_year
|
68
|
-
|
69
|
+
years_ago(1)
|
69
70
|
end
|
70
71
|
|
71
|
-
# Short-hand for
|
72
|
+
# Short-hand for years_since(1)
|
72
73
|
def next_year
|
73
74
|
years_since(1)
|
74
75
|
end
|
@@ -86,7 +87,8 @@ module ActiveSupport #:nodoc:
|
|
86
87
|
|
87
88
|
# Returns a new Time representing the "start" of this week (Monday, 0:00)
|
88
89
|
def beginning_of_week
|
89
|
-
|
90
|
+
days_to_monday = self.wday!=0 ? self.wday-1 : 6
|
91
|
+
(self - days_to_monday.days).midnight
|
90
92
|
end
|
91
93
|
alias :monday :beginning_of_week
|
92
94
|
alias :at_beginning_of_week :beginning_of_week
|
@@ -5,6 +5,12 @@ module ActiveSupport #:nodoc:
|
|
5
5
|
module Time #:nodoc:
|
6
6
|
# Getting times in different convenient string representations and other objects
|
7
7
|
module Conversions
|
8
|
+
DATE_FORMATS = {
|
9
|
+
:db => "%Y-%m-%d %H:%M:%S",
|
10
|
+
:short => "%e %b %H:%M",
|
11
|
+
:long => "%B %e, %Y %H:%M"
|
12
|
+
}
|
13
|
+
|
8
14
|
def self.append_features(klass)
|
9
15
|
super
|
10
16
|
klass.send(:alias_method, :to_default_s, :to_s)
|
@@ -12,12 +18,7 @@ module ActiveSupport #:nodoc:
|
|
12
18
|
end
|
13
19
|
|
14
20
|
def to_formatted_s(format = :default)
|
15
|
-
|
16
|
-
when :default then to_default_s
|
17
|
-
when :db then strftime("%Y-%m-%d %H:%M:%S")
|
18
|
-
when :short then strftime("%e %b %H:%M").strip
|
19
|
-
when :long then strftime("%B %e, %Y %H:%M").strip
|
20
|
-
end
|
21
|
+
DATE_FORMATS[format] ? strftime(DATE_FORMATS[format]).strip : to_default_s
|
21
22
|
end
|
22
23
|
|
23
24
|
def to_date
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/module_attribute_accessors'
|
2
2
|
|
3
|
-
module Dependencies
|
3
|
+
module Dependencies #:nodoc:
|
4
4
|
extend self
|
5
5
|
|
6
6
|
@@loaded = [ ]
|
@@ -14,7 +14,7 @@ module Dependencies
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def depend_on(file_name, swallow_load_errors = false)
|
17
|
-
|
17
|
+
unless loaded.include?(file_name)
|
18
18
|
loaded << file_name
|
19
19
|
|
20
20
|
begin
|
@@ -34,7 +34,7 @@ module Dependencies
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def require_or_load(file_name)
|
37
|
-
file_name = "#{file_name}.rb" unless ! load? ||
|
37
|
+
file_name = "#{file_name}.rb" unless ! load? || file_name[-3..-1] == '.rb'
|
38
38
|
load? ? load(file_name) : require(file_name)
|
39
39
|
end
|
40
40
|
|
@@ -48,12 +48,14 @@ module Dependencies
|
|
48
48
|
# load the relavent files automatically.
|
49
49
|
#
|
50
50
|
# Ruby-style modules are supported, as a folder named 'submodule' will load 'submodule.rb' when available.
|
51
|
-
class LoadingModule < Module
|
51
|
+
class LoadingModule < Module #:nodoc:
|
52
52
|
attr_reader :path
|
53
53
|
attr_reader :root
|
54
54
|
|
55
|
-
|
56
|
-
|
55
|
+
class << self
|
56
|
+
def root(*load_paths)
|
57
|
+
RootLoadingModule.new(*load_paths)
|
58
|
+
end
|
57
59
|
end
|
58
60
|
|
59
61
|
def initialize(root, path=[])
|
@@ -61,7 +63,7 @@ module Dependencies
|
|
61
63
|
@root = root
|
62
64
|
end
|
63
65
|
|
64
|
-
def root?()
|
66
|
+
def root?() self.root == self end
|
65
67
|
def load_paths() self.root.load_paths end
|
66
68
|
|
67
69
|
# Load missing constants if possible.
|
@@ -71,13 +73,15 @@ module Dependencies
|
|
71
73
|
|
72
74
|
# Load the controller class or a parent module.
|
73
75
|
def const_load!(name, file_name = nil)
|
76
|
+
file_name ||= 'application' if root? && name.to_s == 'ApplicationController'
|
74
77
|
path = self.path + [file_name || name]
|
75
78
|
|
76
79
|
load_paths.each do |load_path|
|
77
80
|
fs_path = load_path.filesystem_path(path)
|
78
81
|
next unless fs_path
|
79
82
|
|
80
|
-
|
83
|
+
case
|
84
|
+
when File.directory?(fs_path)
|
81
85
|
new_module = LoadingModule.new(self.root, self.path + [name])
|
82
86
|
self.const_set name, new_module
|
83
87
|
if self.root?
|
@@ -88,7 +92,7 @@ module Dependencies
|
|
88
92
|
Object.const_set(name, new_module)
|
89
93
|
end
|
90
94
|
break
|
91
|
-
|
95
|
+
when File.file?(fs_path)
|
92
96
|
self.root.load_file!(fs_path)
|
93
97
|
|
94
98
|
# Import the loaded constant from Object provided we are the root node.
|
@@ -97,7 +101,7 @@ module Dependencies
|
|
97
101
|
end
|
98
102
|
end
|
99
103
|
|
100
|
-
|
104
|
+
self.const_defined?(name)
|
101
105
|
end
|
102
106
|
|
103
107
|
# Is this name present or loadable?
|
@@ -107,7 +111,7 @@ module Dependencies
|
|
107
111
|
end
|
108
112
|
end
|
109
113
|
|
110
|
-
class RootLoadingModule < LoadingModule
|
114
|
+
class RootLoadingModule < LoadingModule #:nodoc:
|
111
115
|
attr_reader :load_paths
|
112
116
|
|
113
117
|
def initialize(*paths)
|
@@ -133,7 +137,7 @@ module Dependencies
|
|
133
137
|
end
|
134
138
|
|
135
139
|
# This object defines a path from which Constants can be loaded.
|
136
|
-
class ConstantLoadPath
|
140
|
+
class ConstantLoadPath #:nodoc:
|
137
141
|
# Create a new load path with the filesystem path
|
138
142
|
def initialize(root) @root = root end
|
139
143
|
|
@@ -141,7 +145,7 @@ module Dependencies
|
|
141
145
|
# if the path leads to a module, or the path to a file if it leads to an object.
|
142
146
|
def filesystem_path(path, allow_module=true)
|
143
147
|
fs_path = [@root]
|
144
|
-
fs_path += path[0..-2].
|
148
|
+
fs_path += path[0..-2].map {|name| const_name_to_module_name name}
|
145
149
|
|
146
150
|
if allow_module
|
147
151
|
result = File.join(fs_path, const_name_to_module_name(path.last))
|
@@ -150,7 +154,7 @@ module Dependencies
|
|
150
154
|
|
151
155
|
result = File.join(fs_path, const_name_to_file_name(path.last))
|
152
156
|
|
153
|
-
|
157
|
+
File.file?(result) ? result : nil
|
154
158
|
end
|
155
159
|
|
156
160
|
def const_name_to_file_name(name)
|
@@ -164,46 +168,44 @@ module Dependencies
|
|
164
168
|
end
|
165
169
|
|
166
170
|
Object.send(:define_method, :require_or_load) { |file_name| Dependencies.require_or_load(file_name) } unless Object.respond_to?(:require_or_load)
|
167
|
-
Object.send(:define_method, :require_dependency) { |file_name| Dependencies.depend_on(file_name) }
|
168
|
-
Object.send(:define_method, :require_association) { |file_name| Dependencies.associate_with(file_name) }
|
169
|
-
|
170
|
-
class
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
raise NameError.new("uninitialized constant #{class_id}").copy_blame!(e)
|
184
|
-
end
|
171
|
+
Object.send(:define_method, :require_dependency) { |file_name| Dependencies.depend_on(file_name) } unless Object.respond_to?(:require_dependency)
|
172
|
+
Object.send(:define_method, :require_association) { |file_name| Dependencies.associate_with(file_name) } unless Object.respond_to?(:require_association)
|
173
|
+
|
174
|
+
class Module #:nodoc:
|
175
|
+
# Use const_missing to autoload associations so we don't have to
|
176
|
+
# require_association when using single-table inheritance.
|
177
|
+
def const_missing(class_id)
|
178
|
+
if Object.const_defined?(:Controllers) and Object::Controllers.const_available?(class_id)
|
179
|
+
return Object::Controllers.const_get(class_id)
|
180
|
+
end
|
181
|
+
|
182
|
+
begin
|
183
|
+
require_dependency(class_id.to_s.demodulize.underscore)
|
184
|
+
if Object.const_defined?(class_id) then return Object.const_get(class_id) else raise LoadError end
|
185
|
+
rescue LoadError => e
|
186
|
+
raise NameError.new("uninitialized constant #{class_id}").copy_blame!(e)
|
185
187
|
end
|
186
188
|
end
|
189
|
+
end
|
187
190
|
|
191
|
+
class Object #:nodoc:
|
188
192
|
def load(file, *extras)
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
end
|
193
|
+
super(file, *extras)
|
194
|
+
rescue Object => exception
|
195
|
+
exception.blame_file! file
|
196
|
+
raise
|
194
197
|
end
|
195
198
|
|
196
199
|
def require(file, *extras)
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
end
|
200
|
+
super(file, *extras)
|
201
|
+
rescue Object => exception
|
202
|
+
exception.blame_file! file
|
203
|
+
raise
|
202
204
|
end
|
203
205
|
end
|
204
206
|
|
205
207
|
# Add file-blaming to exceptions
|
206
|
-
class Exception
|
208
|
+
class Exception #:nodoc:
|
207
209
|
def blame_file!(file)
|
208
210
|
(@blamed_files ||= []).unshift file
|
209
211
|
end
|
@@ -5,18 +5,24 @@ module Inflector
|
|
5
5
|
|
6
6
|
def pluralize(word)
|
7
7
|
result = word.to_s.dup
|
8
|
-
|
9
|
-
|
8
|
+
|
9
|
+
if uncountable_words.include?(result.downcase)
|
10
|
+
result
|
11
|
+
else
|
12
|
+
plural_rules.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
|
13
|
+
result
|
10
14
|
end
|
11
|
-
return result
|
12
15
|
end
|
13
16
|
|
14
17
|
def singularize(word)
|
15
18
|
result = word.to_s.dup
|
16
|
-
|
17
|
-
|
19
|
+
|
20
|
+
if uncountable_words.include?(result.downcase)
|
21
|
+
result
|
22
|
+
else
|
23
|
+
singular_rules.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
|
24
|
+
result
|
18
25
|
end
|
19
|
-
return result
|
20
26
|
end
|
21
27
|
|
22
28
|
def camelize(lower_case_and_underscored_word)
|
@@ -24,7 +30,7 @@ module Inflector
|
|
24
30
|
end
|
25
31
|
|
26
32
|
def underscore(camel_cased_word)
|
27
|
-
camel_cased_word.to_s.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z])/,'\1_\2').gsub(/([a-z])([A-Z])/,'\1_\2').downcase
|
33
|
+
camel_cased_word.to_s.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase
|
28
34
|
end
|
29
35
|
|
30
36
|
def humanize(lower_case_and_underscored_word)
|
@@ -55,42 +61,64 @@ module Inflector
|
|
55
61
|
end
|
56
62
|
|
57
63
|
private
|
64
|
+
def uncountable_words #:doc
|
65
|
+
%w( equipment information rice money species series fish )
|
66
|
+
end
|
67
|
+
|
58
68
|
def plural_rules #:doc:
|
59
69
|
[
|
60
|
-
|
61
|
-
|
62
|
-
|
70
|
+
[/^(ox)$/i, '\1\2en'], # ox
|
71
|
+
[/([m|l])ouse$/i, '\1ice'], # mouse, louse
|
72
|
+
[/(matr|vert)ix|ex$/i, '\1ices'], # matrix, vertex, index
|
73
|
+
[/(x|ch|ss|sh)$/i, '\1es'], # search, switch, fix, box, process, address
|
63
74
|
[/([^aeiouy]|qu)ies$/i, '\1y'],
|
64
|
-
[/([^aeiouy]|qu)y$/i, '\1ies'],
|
75
|
+
[/([^aeiouy]|qu)y$/i, '\1ies'], # query, ability, agency
|
76
|
+
[/(hive)$/i, '\1s'], # archive, hive
|
65
77
|
[/(?:([^f])fe|([lr])f)$/i, '\1\2ves'], # half, safe, wife
|
66
|
-
[/sis$/i, 'ses'],
|
67
|
-
[/([ti])um$/i, '\1a'],
|
68
|
-
[/(p)erson$/i, '\
|
69
|
-
[/(m)an$/i, '\
|
70
|
-
[/(c)hild$/i, '\
|
71
|
-
|
78
|
+
[/sis$/i, 'ses'], # basis, diagnosis
|
79
|
+
[/([ti])um$/i, '\1a'], # datum, medium
|
80
|
+
[/(p)erson$/i, '\1eople'], # person, salesperson
|
81
|
+
[/(m)an$/i, '\1en'], # man, woman, spokesman
|
82
|
+
[/(c)hild$/i, '\1hildren'], # child
|
83
|
+
[/(buffal|tomat)o$/i, '\1\2oes'], # buffalo, tomato
|
84
|
+
[/(bu)s$/i, '\1\2ses'], # bus
|
85
|
+
[/(alias)/i, '\1es'], # alias
|
86
|
+
[/(octop|vir)us$/i, '\1i'], # octopus, virus - virus has no defined plural (according to Latin/dictionary.com), but viri is better than viruses/viruss
|
87
|
+
[/(ax|cri|test)is$/i, '\1es'], # axis, crisis
|
88
|
+
[/s$/i, 's'], # no change (compatibility)
|
72
89
|
[/$/, 's']
|
73
90
|
]
|
74
91
|
end
|
75
92
|
|
76
93
|
def singular_rules #:doc:
|
77
94
|
[
|
78
|
-
[/(
|
95
|
+
[/(matr)ices$/i, '\1ix'],
|
96
|
+
[/(vert)ices$/i, '\1ex'],
|
97
|
+
[/^(ox)en/i, '\1'],
|
98
|
+
[/(alias)es$/i, '\1'],
|
99
|
+
[/([octop|vir])i$/i, '\1us'],
|
100
|
+
[/(cris|ax|test)es$/i, '\1is'],
|
101
|
+
[/(shoe)s$/i, '\1'],
|
102
|
+
[/(o)es$/i, '\1'],
|
103
|
+
[/(bus)es$/i, '\1'],
|
104
|
+
[/([m|l])ice$/i, '\1ouse'],
|
79
105
|
[/(x|ch|ss|sh)es$/i, '\1'],
|
80
106
|
[/(m)ovies$/i, '\1\2ovie'],
|
81
107
|
[/(s)eries$/i, '\1\2eries'],
|
82
108
|
[/([^aeiouy]|qu)ies$/i, '\1y'],
|
83
109
|
[/([lr])ves$/i, '\1f'],
|
84
110
|
[/(tive)s$/i, '\1'],
|
111
|
+
[/(hive)s$/i, '\1'],
|
85
112
|
[/([^f])ves$/i, '\1fe'],
|
113
|
+
[/(^analy)ses$/i, '\1sis'],
|
86
114
|
[/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '\1\2sis'],
|
87
115
|
[/([ti])a$/i, '\1um'],
|
88
116
|
[/(p)eople$/i, '\1\2erson'],
|
89
|
-
[/(m)en$/i, '\
|
117
|
+
[/(m)en$/i, '\1an'],
|
90
118
|
[/(s)tatus$/i, '\1\2tatus'],
|
91
119
|
[/(c)hildren$/i, '\1\2hild'],
|
92
120
|
[/(n)ews$/i, '\1\2ews'],
|
93
121
|
[/s$/i, '']
|
94
122
|
]
|
95
123
|
end
|
96
|
-
end
|
124
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# Extensions to nil which allow for more helpful error messages for
|
2
|
+
# people who are new to rails.
|
3
|
+
#
|
4
|
+
# The aim is to ensure that when users pass nil to methods where that isn't
|
5
|
+
# appropriate, instead of NoMethodError and the name of some method used
|
6
|
+
# by the framework users will see a message explaining what type of object
|
7
|
+
# was expected.
|
8
|
+
|
9
|
+
class NilClass
|
10
|
+
WHINERS = [ ::ActiveRecord::Base, ::Array ]
|
11
|
+
|
12
|
+
@@method_class_map = Hash.new
|
13
|
+
|
14
|
+
WHINERS.each do |klass|
|
15
|
+
methods = klass.public_instance_methods - public_instance_methods
|
16
|
+
methods.each do |method|
|
17
|
+
@@method_class_map[method.to_sym] = klass
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def id
|
22
|
+
raise RuntimeError, "Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id", caller
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
def method_missing(method, *args, &block)
|
27
|
+
if @@method_class_map.include?(method)
|
28
|
+
raise_nil_warning_for @@method_class_map[method], caller
|
29
|
+
else
|
30
|
+
super
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def raise_nil_warning_for(klass, with_caller = nil)
|
35
|
+
raise NoMethodError, NIL_WARNING_MESSAGE % klass, with_caller || caller
|
36
|
+
end
|
37
|
+
|
38
|
+
NIL_WARNING_MESSAGE = <<-end_message unless const_defined?(:NIL_WARNING_MESSAGE)
|
39
|
+
WARNING: You have a nil object when you probably didn't expect it! Odds are you
|
40
|
+
want an instance of %s instead.
|
41
|
+
|
42
|
+
Look in the callstack to see where you're working with an object that could be nil.
|
43
|
+
Investigate your methods and make sure the object is what you expect!
|
44
|
+
end_message
|
45
|
+
end
|
46
|
+
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.8.
|
2
|
+
rubygems_version: 0.8.10
|
3
3
|
specification_version: 1
|
4
4
|
name: activesupport
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.0
|
7
|
-
date: 2005-
|
6
|
+
version: 1.1.0
|
7
|
+
date: 2005-07-06
|
8
8
|
summary: Support and utility classes used by the Rails framework.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -42,6 +42,11 @@ files:
|
|
42
42
|
- lib/active_support/misc.rb
|
43
43
|
- lib/active_support/module_attribute_accessors.rb
|
44
44
|
- lib/active_support/values
|
45
|
+
- lib/active_support/whiny_nil.rb
|
46
|
+
- lib/active_support/core_ext/array
|
47
|
+
- lib/active_support/core_ext/array.rb
|
48
|
+
- lib/active_support/core_ext/cgi
|
49
|
+
- lib/active_support/core_ext/cgi.rb
|
45
50
|
- lib/active_support/core_ext/date
|
46
51
|
- lib/active_support/core_ext/date.rb
|
47
52
|
- lib/active_support/core_ext/fixnum
|
@@ -57,6 +62,8 @@ files:
|
|
57
62
|
- lib/active_support/core_ext/string.rb
|
58
63
|
- lib/active_support/core_ext/time
|
59
64
|
- lib/active_support/core_ext/time.rb
|
65
|
+
- lib/active_support/core_ext/array/to_param.rb
|
66
|
+
- lib/active_support/core_ext/cgi/escape_skipping_slashes.rb
|
60
67
|
- lib/active_support/core_ext/date/conversions.rb
|
61
68
|
- lib/active_support/core_ext/fixnum/even_odd.rb
|
62
69
|
- lib/active_support/core_ext/hash/indifferent_access.rb
|