activesupport 1.1.1 → 1.2.1
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 +83 -0
- data/lib/active_support.rb +2 -1
- data/lib/active_support/clean_logger.rb +14 -6
- data/lib/active_support/core_ext/array.rb +2 -2
- data/lib/active_support/core_ext/array/conversions.rb +30 -0
- data/lib/active_support/core_ext/blank.rb +36 -0
- data/lib/active_support/core_ext/date/conversions.rb +1 -2
- data/lib/active_support/core_ext/enumerable.rb +9 -0
- data/lib/active_support/core_ext/exception.rb +29 -0
- data/lib/active_support/core_ext/hash.rb +2 -0
- data/lib/active_support/core_ext/hash/keys.rb +2 -2
- data/lib/active_support/core_ext/hash/reverse_merge.rb +25 -0
- data/lib/active_support/core_ext/integer.rb +7 -0
- data/lib/active_support/core_ext/{fixnum → integer}/even_odd.rb +1 -1
- data/lib/active_support/core_ext/integer/inflections.rb +15 -0
- data/lib/active_support/core_ext/kernel.rb +36 -0
- data/lib/active_support/core_ext/object_and_class.rb +0 -9
- data/lib/active_support/core_ext/range.rb +5 -0
- data/lib/active_support/core_ext/range/conversions.rb +21 -0
- data/lib/active_support/core_ext/string.rb +5 -1
- data/lib/active_support/core_ext/string/access.rb +58 -0
- data/lib/active_support/core_ext/string/inflections.rb +2 -0
- data/lib/active_support/core_ext/string/starts_ends_with.rb +20 -0
- data/lib/active_support/core_ext/time/calculations.rb +44 -13
- data/lib/active_support/core_ext/time/conversions.rb +5 -4
- data/lib/active_support/dependencies.rb +15 -2
- data/lib/active_support/inflections.rb +53 -0
- data/lib/active_support/inflector.rb +105 -69
- data/lib/active_support/ordered_options.rb +31 -0
- data/lib/active_support/version.rb +9 -0
- data/lib/active_support/whiny_nil.rb +7 -15
- metadata +19 -7
- data/lib/active_support/core_ext/array/to_param.rb +0 -12
- data/lib/active_support/core_ext/fixnum.rb +0 -9
- data/lib/active_support/misc.rb +0 -8
data/CHANGELOG
CHANGED
@@ -1,3 +1,86 @@
|
|
1
|
+
*1.2.1* (October 19th, 2005)
|
2
|
+
|
3
|
+
* Classify generated routing code as framework code to avoid appearing in application traces. [Nicholas Seckar]
|
4
|
+
|
5
|
+
* Show all framework frames in the framework trace. [Nicholas Seckar]
|
6
|
+
|
7
|
+
|
8
|
+
*1.2.0* (October 16th, 2005)
|
9
|
+
|
10
|
+
* Update Exception extension to show the first few framework frames in an application trace. [Nicholas Seckar]
|
11
|
+
|
12
|
+
* Added Exception extension to provide support for clean backtraces. [Nicholas Seckar]
|
13
|
+
|
14
|
+
* Updated whiny nil to be more concise and useful. [Nicholas Seckar]
|
15
|
+
|
16
|
+
* Added Enumerable#first_match [Nicholas Seckar]
|
17
|
+
|
18
|
+
* Fixed that Time#change should also reset usec when also resetting minutes #2459 [ikeda@dream.big.or.jp]
|
19
|
+
|
20
|
+
* Fix Logger compatibility for distributions that don't keep Ruby and its standard library in sync.
|
21
|
+
|
22
|
+
* Replace '%e' from long and short time formats as Windows does not support it. #2344. [Tom Ward <tom@popdog.net>]
|
23
|
+
|
24
|
+
* Added to_s(:db) to Range, so you can get "BETWEEN '2005-12-10' AND '2005-12-12'" from Date.new(2005, 12, 10)..Date.new(2005, 12, 12) (and likewise with Times)
|
25
|
+
|
26
|
+
* Moved require_library_or_gem into Kernel. #1992 [Michael Schuerig <michael@schuerig.de>]
|
27
|
+
|
28
|
+
* Add :rfc822 as an option for Time#to_s (to get rfc822-formatted times)
|
29
|
+
|
30
|
+
* Chain the const_missing hook to any previously existing hook so rails can play nicely with rake
|
31
|
+
|
32
|
+
* Clean logger is compatible with both 1.8.2 and 1.8.3 Logger. #2263 [Michael Schuerig <michael@schuerig.de>]
|
33
|
+
|
34
|
+
* Added native, faster implementations of .blank? for the core types #2286 [skae]
|
35
|
+
|
36
|
+
* Fixed clean logger to work with Ruby 1.8.3 Logger class #2245
|
37
|
+
|
38
|
+
* Fixed memory leak with Active Record classes when Dependencies.mechanism = :load #1704 [c.r.mcgrath@gmail.com]
|
39
|
+
|
40
|
+
* Fixed Inflector.underscore for use with acronyms, so HTML becomes html instead of htm_l #2173 [k@v2studio.com]
|
41
|
+
|
42
|
+
* Fixed dependencies related infinite recursion bug when a controller file does not contain a controller class. Closes #1760. [rcolli2@tampabay.rr.com]
|
43
|
+
|
44
|
+
* Fixed inflections for status, quiz, move #2056 [deirdre@deirdre.net]
|
45
|
+
|
46
|
+
* Added Hash#reverse_merge, Hash#reverse_merge!, and Hash#reverse_update to ease the use of default options
|
47
|
+
|
48
|
+
* Added Array#to_sentence that'll turn ['one', 'two', 'three'] into "one, two, and three" #2157 [m.stienstra@fngtps.com]
|
49
|
+
|
50
|
+
* Added Kernel#silence_warnings to turn off warnings temporarily for the passed block
|
51
|
+
|
52
|
+
* Added String#starts_with? and String#ends_with? #2118 [thijs@vandervossen.net]
|
53
|
+
|
54
|
+
* Added easy extendability to the inflector through Inflector.inflections (using the Inflector::Inflections singleton class). Examples:
|
55
|
+
|
56
|
+
Inflector.inflections do |inflect|
|
57
|
+
inflect.plural /^(ox)$/i, '\1\2en'
|
58
|
+
inflect.singular /^(ox)en/i, '\1'
|
59
|
+
|
60
|
+
inflect.irregular 'octopus', 'octopi'
|
61
|
+
|
62
|
+
inflect.uncountable "equipment"
|
63
|
+
end
|
64
|
+
|
65
|
+
* Added String#at, String#from, String#to, String#first, String#last in ActiveSupport::CoreExtensions::String::Access to ease access to individual characters and substrings in a string serving basically as human names for range access.
|
66
|
+
|
67
|
+
* Make Time#last_month work when invoked on the 31st of a month.
|
68
|
+
|
69
|
+
* Add Time.days_in_month, and make Time#next_month work when invoked on the 31st of a month
|
70
|
+
|
71
|
+
* Fixed that Time#midnight would have a non-zero usec on some platforms #1836
|
72
|
+
|
73
|
+
* Fixed inflections of "index/indices" #1766 [damn_pepe@gmail.com]
|
74
|
+
|
75
|
+
* Added stripping of _id to String#humanize, so "employee_id" becomes "Employee" #1574 [Justin French]
|
76
|
+
|
77
|
+
* Factor Fixnum and Bignum extensions into Integer extensions [Nicholas Seckar]
|
78
|
+
|
79
|
+
* Hooked #ordinalize into Fixnum and Bignum classes. [Nicholas Seckar, danp]
|
80
|
+
|
81
|
+
* Added Fixnum#ordinalize to turn 1.ordinalize to "1st", 3.ordinalize to "3rd", and 10.ordinalize to "10th" and so on #1724 [paul@cnt.org]
|
82
|
+
|
83
|
+
|
1
84
|
*1.1.1* (11 July, 2005)
|
2
85
|
|
3
86
|
* Added more efficient implementation of the development mode reset of classes #1638 [Chris McGrath]
|
data/lib/active_support.rb
CHANGED
@@ -29,7 +29,8 @@ require 'active_support/inflector'
|
|
29
29
|
|
30
30
|
require 'active_support/core_ext'
|
31
31
|
require 'active_support/clean_logger'
|
32
|
-
require 'active_support/misc'
|
33
32
|
require 'active_support/dependencies'
|
34
33
|
|
34
|
+
require 'active_support/ordered_options'
|
35
|
+
|
35
36
|
require 'active_support/values/time_zone'
|
@@ -4,15 +4,23 @@ class Logger #:nodoc:
|
|
4
4
|
# Silences the logger for the duration of the block.
|
5
5
|
def silence(temporary_level = Logger::ERROR)
|
6
6
|
old_logger_level, self.level = level, temporary_level
|
7
|
-
yield
|
7
|
+
yield self
|
8
8
|
ensure
|
9
9
|
self.level = old_logger_level
|
10
10
|
end
|
11
11
|
|
12
12
|
private
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
# Ruby 1.8.3 transposed the msg and progname arguments to format_message.
|
14
|
+
# We can't test RUBY_VERSION because some distributions don't keep Ruby
|
15
|
+
# and its standard library in sync, leading to installations of Ruby 1.8.2
|
16
|
+
# with Logger from 1.8.3 and vice versa.
|
17
|
+
if method_defined?(:formatter=)
|
18
|
+
def format_message(severity, timestamp, progname, msg)
|
19
|
+
"#{msg}\n"
|
20
|
+
end
|
21
|
+
else
|
22
|
+
def format_message(severity, timestamp, msg, progname)
|
23
|
+
"#{msg}\n"
|
24
|
+
end
|
17
25
|
end
|
18
|
-
end
|
26
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module ActiveSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module Array #:nodoc:
|
4
|
+
# Enables to conversion of Arrays to human readable lists. ['one', 'two', 'three'] => "one, two, and three"
|
5
|
+
module Conversions
|
6
|
+
# Converts the array to comma-seperated sentence where the last element is joined by the connector word. Options:
|
7
|
+
# * <tt>:connector</tt>: The word used to join the last element in arrays with more than two elements (default: "and")
|
8
|
+
# * <tt>:skip_last_comma</tt>: Set to true to return "a, b and c" instead of "a, b, and c".
|
9
|
+
def to_sentence(options = {})
|
10
|
+
options.assert_valid_keys(:connector, :skip_last_comma)
|
11
|
+
options.reverse_merge! :connector => 'and', :skip_last_comma => false
|
12
|
+
|
13
|
+
case length
|
14
|
+
when 1
|
15
|
+
self[0]
|
16
|
+
when 2
|
17
|
+
"#{self[0]} #{options[:connector]} #{self[1]}"
|
18
|
+
else
|
19
|
+
"#{self[0...-1].join(', ')}#{options[:skip_last_comma] ? '' : ','} #{options[:connector]} #{self[-1]}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# When an array is given to url_for, it is converted to a slash separated string.
|
24
|
+
def to_param
|
25
|
+
join '/'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# The methods here are provided to speed up function blank? in class Object
|
2
|
+
class NilClass #:nodoc:
|
3
|
+
def blank?
|
4
|
+
true
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class FalseClass #:nodoc:
|
9
|
+
def blank?
|
10
|
+
true
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class TrueClass #:nodoc:
|
15
|
+
def blank?
|
16
|
+
false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Array #:nodoc:
|
21
|
+
alias_method :blank?, :empty?
|
22
|
+
end
|
23
|
+
|
24
|
+
class Hash #:nodoc:
|
25
|
+
alias_method :blank?, :empty?
|
26
|
+
end
|
27
|
+
|
28
|
+
class String #:nodoc:
|
29
|
+
def blank?
|
30
|
+
empty? || strip.empty?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Numeric #:nodoc:
|
35
|
+
alias_method :blank?, :zero?
|
36
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Exception
|
2
|
+
|
3
|
+
alias :clean_message :message
|
4
|
+
|
5
|
+
TraceSubstitutions = []
|
6
|
+
FrameworkRegexp = /generated_code|vendor|dispatch|ruby|script\/\w+/
|
7
|
+
|
8
|
+
def clean_backtrace
|
9
|
+
backtrace.collect do |line|
|
10
|
+
TraceSubstitutions.inject(line) do |line, (regexp, sub)|
|
11
|
+
line.gsub regexp, sub
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def application_backtrace
|
17
|
+
before_application_frame = true
|
18
|
+
|
19
|
+
clean_backtrace.reject do |line|
|
20
|
+
non_app_frame = !! (line =~ FrameworkRegexp)
|
21
|
+
before_application_frame = false unless non_app_frame
|
22
|
+
non_app_frame && ! before_application_frame
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def framework_backtrace
|
27
|
+
clean_backtrace.select {|line| line =~ FrameworkRegexp}
|
28
|
+
end
|
29
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/hash/keys'
|
2
2
|
require File.dirname(__FILE__) + '/hash/indifferent_access'
|
3
|
+
require File.dirname(__FILE__) + '/hash/reverse_merge'
|
3
4
|
|
4
5
|
class Hash #:nodoc:
|
5
6
|
include ActiveSupport::CoreExtensions::Hash::Keys
|
6
7
|
include ActiveSupport::CoreExtensions::Hash::IndifferentAccess
|
8
|
+
include ActiveSupport::CoreExtensions::Hash::ReverseMerge
|
7
9
|
end
|
@@ -43,8 +43,8 @@ module ActiveSupport #:nodoc:
|
|
43
43
|
alias_method :to_options, :symbolize_keys
|
44
44
|
alias_method :to_options!, :symbolize_keys!
|
45
45
|
|
46
|
-
def assert_valid_keys(valid_keys)
|
47
|
-
unknown_keys = keys - valid_keys
|
46
|
+
def assert_valid_keys(*valid_keys)
|
47
|
+
unknown_keys = keys - [valid_keys].flatten
|
48
48
|
raise(ArgumentError, "Unknown key(s): #{unknown_keys.join(", ")}") unless unknown_keys.empty?
|
49
49
|
end
|
50
50
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module ActiveSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module Hash #:nodoc:
|
4
|
+
# Allows for reverse merging where its the keys in the calling hash that wins over those in the <tt>other_hash</tt>.
|
5
|
+
# This is particularly useful for initializing an incoming option hash with default values:
|
6
|
+
#
|
7
|
+
# def setup(options = {})
|
8
|
+
# options.reverse_merge! :size => 25, :velocity => 10
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# The default :size and :velocity is only set if the +options+ passed in doesn't already have those keys set.
|
12
|
+
module ReverseMerge
|
13
|
+
def reverse_merge(other_hash)
|
14
|
+
other_hash.merge(self)
|
15
|
+
end
|
16
|
+
|
17
|
+
def reverse_merge!(other_hash)
|
18
|
+
replace(reverse_merge(other_hash))
|
19
|
+
end
|
20
|
+
|
21
|
+
alias_method :reverse_update, :reverse_merge
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../inflector'
|
2
|
+
module ActiveSupport #:nodoc:
|
3
|
+
module CoreExtensions #:nodoc:
|
4
|
+
module Integer #:nodoc:
|
5
|
+
module Inflections
|
6
|
+
# 1.ordinalize # => "1st"
|
7
|
+
# 3.ordinalize # => "3rd"
|
8
|
+
# 10.ordinalize # => "10th"
|
9
|
+
def ordinalize
|
10
|
+
Inflector.ordinalize(self)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -14,4 +14,40 @@ module Kernel
|
|
14
14
|
yield
|
15
15
|
value
|
16
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
|
+
# Method that requires a library, ensuring that rubygems is loaded
|
33
|
+
def require_library_or_gem(library_name)
|
34
|
+
begin
|
35
|
+
require library_name
|
36
|
+
rescue LoadError => cannot_require
|
37
|
+
# 1. Requiring the module is unsuccessful, maybe it's a gem and nobody required rubygems yet. Try.
|
38
|
+
begin
|
39
|
+
require 'rubygems'
|
40
|
+
rescue LoadError => rubygems_not_installed
|
41
|
+
raise cannot_require
|
42
|
+
end
|
43
|
+
# 2. Rubygems is installed and loaded. Try to load the library again
|
44
|
+
begin
|
45
|
+
require library_name
|
46
|
+
rescue LoadError => gem_not_installed
|
47
|
+
raise cannot_require
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
17
53
|
end
|
@@ -1,19 +1,10 @@
|
|
1
1
|
class Object #:nodoc:
|
2
2
|
def remove_subclasses_of(*superclasses)
|
3
3
|
subclasses_of(*superclasses).each do |subclass|
|
4
|
-
subclass.instance_variables.each { |v| subclass.send(:remove_instance_variable, v) }
|
5
4
|
Object.send(:remove_const, subclass.to_s) rescue nil
|
6
5
|
end
|
7
6
|
end
|
8
7
|
|
9
|
-
def remove_instance_variables_of(klass)
|
10
|
-
ObjectSpace.each_object(Class) do |k|
|
11
|
-
if k.to_s == klass
|
12
|
-
k.instance_variables.each { |v| k.send(:remove_instance_variable, v) }
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
8
|
def subclasses_of(*superclasses)
|
18
9
|
subclasses = []
|
19
10
|
ObjectSpace.each_object(Class) do |k|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ActiveSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module Range #:nodoc:
|
4
|
+
# Getting dates in different convenient string representations and other objects
|
5
|
+
module Conversions
|
6
|
+
DATE_FORMATS = {
|
7
|
+
:db => Proc.new { |start, stop| "BETWEEN '#{start.to_s(:db)}' AND '#{stop.to_s(:db)}'" }
|
8
|
+
}
|
9
|
+
|
10
|
+
def self.included(klass) #:nodoc:
|
11
|
+
klass.send(:alias_method, :to_default_s, :to_s)
|
12
|
+
klass.send(:alias_method, :to_s, :to_formatted_s)
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_formatted_s(format = :default)
|
16
|
+
DATE_FORMATS[format] ? DATE_FORMATS[format].call(first, last) : to_default_s
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,7 +1,11 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/string/inflections'
|
2
2
|
require File.dirname(__FILE__) + '/string/conversions'
|
3
|
+
require File.dirname(__FILE__) + '/string/access'
|
4
|
+
require File.dirname(__FILE__) + '/string/starts_ends_with'
|
3
5
|
|
4
6
|
class String #:nodoc:
|
5
|
-
include ActiveSupport::CoreExtensions::String::
|
7
|
+
include ActiveSupport::CoreExtensions::String::Access
|
6
8
|
include ActiveSupport::CoreExtensions::String::Conversions
|
9
|
+
include ActiveSupport::CoreExtensions::String::Inflections
|
10
|
+
include ActiveSupport::CoreExtensions::String::StartsEndsWith
|
7
11
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module ActiveSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module String #:nodoc:
|
4
|
+
# Makes it easier to access parts of a string, such as specific characters and substrings.
|
5
|
+
module Access
|
6
|
+
# Returns the character at the +position+ treating the string as an array (where 0 is the first character).
|
7
|
+
#
|
8
|
+
# Examples:
|
9
|
+
# "hello".at(0) # => "h"
|
10
|
+
# "hello".at(4) # => "o"
|
11
|
+
# "hello".at(10) # => nil
|
12
|
+
def at(position)
|
13
|
+
self[position, 1]
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns the remaining of the string from the +position+ treating the string as an array (where 0 is the first character).
|
17
|
+
#
|
18
|
+
# Examples:
|
19
|
+
# "hello".from(0) # => "hello"
|
20
|
+
# "hello".from(2) # => "llo"
|
21
|
+
# "hello".from(10) # => nil
|
22
|
+
def from(position)
|
23
|
+
self[position..-1]
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns the beginning of the string up to the +position+ treating the string as an array (where 0 is the first character).
|
27
|
+
#
|
28
|
+
# Examples:
|
29
|
+
# "hello".to(0) # => "h"
|
30
|
+
# "hello".to(2) # => "hel"
|
31
|
+
# "hello".to(10) # => "hello"
|
32
|
+
def to(position)
|
33
|
+
self[0..position]
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns the first character of the string or the first +limit+ characters.
|
37
|
+
#
|
38
|
+
# Examples:
|
39
|
+
# "hello".first # => "h"
|
40
|
+
# "hello".first(2) # => "he"
|
41
|
+
# "hello".first(10) # => "hello"
|
42
|
+
def first(limit = 1)
|
43
|
+
self[0..(limit - 1)]
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns the last character of the string or the last +limit+ characters.
|
47
|
+
#
|
48
|
+
# Examples:
|
49
|
+
# "hello".last # => "o"
|
50
|
+
# "hello".last(2) # => "lo"
|
51
|
+
# "hello".last(10) # => "hello"
|
52
|
+
def last(limit = 1)
|
53
|
+
self[(-limit)..-1]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -32,6 +32,8 @@ module ActiveSupport #:nodoc:
|
|
32
32
|
Inflector.classify(self)
|
33
33
|
end
|
34
34
|
|
35
|
+
# Capitalizes the first word and turns underscores into spaces and strips _id, so "employee_salary" becomes "Employee salary"
|
36
|
+
# and "author_id" becomes "Author".
|
35
37
|
def humanize
|
36
38
|
Inflector.humanize(self)
|
37
39
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module ActiveSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module String #:nodoc:
|
4
|
+
# Additional string tests.
|
5
|
+
module StartsEndsWith
|
6
|
+
# Does the string start with the specified +prefix+?
|
7
|
+
def starts_with?(prefix)
|
8
|
+
prefix = prefix.to_s
|
9
|
+
self[0, prefix.length] == prefix
|
10
|
+
end
|
11
|
+
|
12
|
+
# Does the string end with the specified +suffix+?
|
13
|
+
def ends_with?(suffix)
|
14
|
+
suffix = suffix.to_s
|
15
|
+
self[-suffix.length, suffix.length] == suffix
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -3,6 +3,27 @@ module ActiveSupport #:nodoc:
|
|
3
3
|
module Time #:nodoc:
|
4
4
|
# Enables the use of time calculations within Time itself
|
5
5
|
module Calculations
|
6
|
+
def self.append_features(base) #:nodoc:
|
7
|
+
super
|
8
|
+
base.extend(ClassMethods)
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
# Return the number of days in the given month. If a year is given,
|
13
|
+
# February will return the correct number of days for leap years.
|
14
|
+
# Otherwise, this method will always report February as having 28
|
15
|
+
# days.
|
16
|
+
def days_in_month(month, year=nil)
|
17
|
+
if month == 2
|
18
|
+
!year.nil? && (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)) ? 29 : 28
|
19
|
+
elsif month <= 7
|
20
|
+
month % 2 == 0 ? 30 : 31
|
21
|
+
else
|
22
|
+
month % 2 == 0 ? 31 : 30
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
6
27
|
# Seconds since midnight: Time.now.seconds_since_midnight
|
7
28
|
def seconds_since_midnight
|
8
29
|
self.hour.hours + self.min.minutes + self.sec + (self.usec/1.0e+6)
|
@@ -20,7 +41,7 @@ module ActiveSupport #:nodoc:
|
|
20
41
|
options[:hour] || self.hour,
|
21
42
|
options[:min] || (options[:hour] ? 0 : self.min),
|
22
43
|
options[:sec] || ((options[:hour] || options[:min]) ? 0 : self.sec),
|
23
|
-
options[:usec] || ((options[:hour] || options[:min] || options[:
|
44
|
+
options[:usec] || ((options[:hour] || options[:min] || options[:sec]) ? 0 : self.usec)
|
24
45
|
)
|
25
46
|
end
|
26
47
|
|
@@ -39,20 +60,30 @@ module ActiveSupport #:nodoc:
|
|
39
60
|
|
40
61
|
# Returns a new Time representing the time a number of specified months ago
|
41
62
|
def months_ago(months)
|
42
|
-
|
43
|
-
change(:year => self.year - 1, :month => 12).months_ago(months - self.month)
|
44
|
-
else
|
45
|
-
change(:year => self.year, :month => self.month - months)
|
46
|
-
end
|
63
|
+
months_since(-months)
|
47
64
|
end
|
48
65
|
|
49
66
|
def months_since(months)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
67
|
+
year, month, mday = self.year, self.month, self.mday
|
68
|
+
|
69
|
+
month += months
|
70
|
+
|
71
|
+
# in case months is negative
|
72
|
+
while month < 1
|
73
|
+
month += 12
|
74
|
+
year -= 1
|
75
|
+
end
|
76
|
+
|
77
|
+
# in case months is positive
|
78
|
+
while month > 12
|
79
|
+
month -= 12
|
80
|
+
year += 1
|
55
81
|
end
|
82
|
+
|
83
|
+
max = ::Time.days_in_month(month, year)
|
84
|
+
mday = max if mday > max
|
85
|
+
|
86
|
+
change(:year => year, :month => month, :mday => mday)
|
56
87
|
end
|
57
88
|
|
58
89
|
# Returns a new Time representing the time a number of specified years ago
|
@@ -101,7 +132,7 @@ module ActiveSupport #:nodoc:
|
|
101
132
|
|
102
133
|
# Returns a new Time representing the start of the day (0:00)
|
103
134
|
def beginning_of_day
|
104
|
-
self - self.seconds_since_midnight
|
135
|
+
(self - self.seconds_since_midnight).change(:usec => 0)
|
105
136
|
end
|
106
137
|
alias :midnight :beginning_of_day
|
107
138
|
alias :at_midnight :beginning_of_day
|
@@ -132,4 +163,4 @@ module ActiveSupport #:nodoc:
|
|
132
163
|
end
|
133
164
|
end
|
134
165
|
end
|
135
|
-
end
|
166
|
+
end
|
@@ -6,9 +6,10 @@ module ActiveSupport #:nodoc:
|
|
6
6
|
# Getting times in different convenient string representations and other objects
|
7
7
|
module Conversions
|
8
8
|
DATE_FORMATS = {
|
9
|
-
:db
|
10
|
-
:short
|
11
|
-
:long
|
9
|
+
:db => "%Y-%m-%d %H:%M:%S",
|
10
|
+
:short => "%d %b %H:%M",
|
11
|
+
:long => "%B %d, %Y %H:%M",
|
12
|
+
:rfc822 => "%a, %d %b %Y %H:%M:%S %z"
|
12
13
|
}
|
13
14
|
|
14
15
|
def self.append_features(klass)
|
@@ -32,4 +33,4 @@ module ActiveSupport #:nodoc:
|
|
32
33
|
end
|
33
34
|
end
|
34
35
|
end
|
35
|
-
end
|
36
|
+
end
|
@@ -93,10 +93,16 @@ module Dependencies #:nodoc:
|
|
93
93
|
end
|
94
94
|
break
|
95
95
|
when File.file?(fs_path)
|
96
|
-
self.root.load_file!(fs_path)
|
96
|
+
loaded_file = self.root.load_file!(fs_path)
|
97
97
|
|
98
98
|
# Import the loaded constant from Object provided we are the root node.
|
99
99
|
self.const_set(name, Object.const_get(name)) if self.root? && Object.const_defined?(name)
|
100
|
+
|
101
|
+
# Throw an error if we load the file but we don't find the Object we expect
|
102
|
+
if loaded_file and not self.const_defined?(name)
|
103
|
+
msg = "Already loaded file '#{fs_path}' but '#{name.to_s}' was not set, perhaps you need to rename '#{fs_path}'?"
|
104
|
+
raise LoadError, msg
|
105
|
+
end
|
100
106
|
break
|
101
107
|
end
|
102
108
|
end
|
@@ -172,6 +178,9 @@ Object.send(:define_method, :require_dependency) { |file_name| Dependencies.dep
|
|
172
178
|
Object.send(:define_method, :require_association) { |file_name| Dependencies.associate_with(file_name) } unless Object.respond_to?(:require_association)
|
173
179
|
|
174
180
|
class Module #:nodoc:
|
181
|
+
# Rename the original handler so we can chain it to the new one
|
182
|
+
alias :rails_original_const_missing :const_missing
|
183
|
+
|
175
184
|
# Use const_missing to autoload associations so we don't have to
|
176
185
|
# require_association when using single-table inheritance.
|
177
186
|
def const_missing(class_id)
|
@@ -183,7 +192,11 @@ class Module #:nodoc:
|
|
183
192
|
require_dependency(class_id.to_s.demodulize.underscore)
|
184
193
|
if Object.const_defined?(class_id) then return Object.const_get(class_id) else raise LoadError end
|
185
194
|
rescue LoadError => e
|
186
|
-
|
195
|
+
begin
|
196
|
+
rails_original_const_missing(class_id)
|
197
|
+
rescue Exception
|
198
|
+
raise NameError.new("uninitialized constant #{class_id}").copy_blame!(e)
|
199
|
+
end
|
187
200
|
end
|
188
201
|
end
|
189
202
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
Inflector.inflections do |inflect|
|
2
|
+
inflect.plural /$/, 's'
|
3
|
+
inflect.plural /s$/i, 's'
|
4
|
+
inflect.plural /(ax|test)is$/i, '\1es'
|
5
|
+
inflect.plural /(octop|vir)us$/i, '\1i'
|
6
|
+
inflect.plural /(alias|status)/i, '\1es'
|
7
|
+
inflect.plural /(bu)s$/i, '\1ses'
|
8
|
+
inflect.plural /(buffal|tomat)o$/i, '\1oes'
|
9
|
+
inflect.plural /([ti])um$/i, '\1a'
|
10
|
+
inflect.plural /sis$/i, 'ses'
|
11
|
+
inflect.plural /(?:([^f])fe|([lr])f)$/i, '\1\2ves'
|
12
|
+
inflect.plural /(hive)$/i, '\1s'
|
13
|
+
inflect.plural /([^aeiouy]|qu)y$/i, '\1ies'
|
14
|
+
inflect.plural /([^aeiouy]|qu)ies$/i, '\1y'
|
15
|
+
inflect.plural /(x|ch|ss|sh)$/i, '\1es'
|
16
|
+
inflect.plural /(matr|vert|ind)ix|ex$/i, '\1ices'
|
17
|
+
inflect.plural /([m|l])ouse$/i, '\1ice'
|
18
|
+
inflect.plural /^(ox)$/i, '\1en'
|
19
|
+
inflect.plural /(quiz)$/i, '\1zes'
|
20
|
+
|
21
|
+
inflect.singular /s$/i, ''
|
22
|
+
inflect.singular /(n)ews$/i, '\1ews'
|
23
|
+
inflect.singular /([ti])a$/i, '\1um'
|
24
|
+
inflect.singular /((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '\1\2sis'
|
25
|
+
inflect.singular /(^analy)ses$/i, '\1sis'
|
26
|
+
inflect.singular /([^f])ves$/i, '\1fe'
|
27
|
+
inflect.singular /(hive)s$/i, '\1'
|
28
|
+
inflect.singular /(tive)s$/i, '\1'
|
29
|
+
inflect.singular /([lr])ves$/i, '\1f'
|
30
|
+
inflect.singular /([^aeiouy]|qu)ies$/i, '\1y'
|
31
|
+
inflect.singular /(s)eries$/i, '\1eries'
|
32
|
+
inflect.singular /(m)ovies$/i, '\1ovie'
|
33
|
+
inflect.singular /(x|ch|ss|sh)es$/i, '\1'
|
34
|
+
inflect.singular /([m|l])ice$/i, '\1ouse'
|
35
|
+
inflect.singular /(bus)es$/i, '\1'
|
36
|
+
inflect.singular /(o)es$/i, '\1'
|
37
|
+
inflect.singular /(shoe)s$/i, '\1'
|
38
|
+
inflect.singular /(cris|ax|test)es$/i, '\1is'
|
39
|
+
inflect.singular /([octop|vir])i$/i, '\1us'
|
40
|
+
inflect.singular /(alias|status)es$/i, '\1'
|
41
|
+
inflect.singular /^(ox)en/i, '\1'
|
42
|
+
inflect.singular /(vert|ind)ices$/i, '\1ex'
|
43
|
+
inflect.singular /(matr)ices$/i, '\1ix'
|
44
|
+
inflect.singular /(quiz)zes$/i, '\1'
|
45
|
+
|
46
|
+
inflect.irregular 'person', 'people'
|
47
|
+
inflect.irregular 'man', 'men'
|
48
|
+
inflect.irregular 'child', 'children'
|
49
|
+
inflect.irregular 'sex', 'sexes'
|
50
|
+
inflect.irregular 'move', 'moves'
|
51
|
+
|
52
|
+
inflect.uncountable %w( equipment information rice money species series fish sheep )
|
53
|
+
end
|
@@ -1,15 +1,99 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
1
3
|
# The Inflector transforms words from singular to plural, class names to table names, modularized class names to ones without,
|
2
|
-
# and class names to foreign keys.
|
4
|
+
# and class names to foreign keys. The default inflections for pluralization, singularization, and uncountable words are kept
|
5
|
+
# in inflections.rb.
|
3
6
|
module Inflector
|
7
|
+
# A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional
|
8
|
+
# inflection rules. Examples:
|
9
|
+
#
|
10
|
+
# Inflector.inflections do |inflect|
|
11
|
+
# inflect.plural /^(ox)$/i, '\1\2en'
|
12
|
+
# inflect.singular /^(ox)en/i, '\1'
|
13
|
+
#
|
14
|
+
# inflect.irregular 'octopus', 'octopi'
|
15
|
+
#
|
16
|
+
# inflect.uncountable "equipment"
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# New rules are added at the top. So in the example above, the irregular rule for octopus will now be the first of the
|
20
|
+
# pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may
|
21
|
+
# already have been loaded.
|
22
|
+
class Inflections
|
23
|
+
include Singleton
|
24
|
+
|
25
|
+
attr_reader :plurals, :singulars, :uncountables
|
26
|
+
|
27
|
+
def initialize
|
28
|
+
@plurals, @singulars, @uncountables = [], [], []
|
29
|
+
end
|
30
|
+
|
31
|
+
# Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression.
|
32
|
+
# The replacement should always be a string that may include references to the matched data from the rule.
|
33
|
+
def plural(rule, replacement)
|
34
|
+
@plurals.insert(0, [rule, replacement])
|
35
|
+
end
|
36
|
+
|
37
|
+
# Specifies a new singularization rule and its replacement. The rule can either be a string or a regular expression.
|
38
|
+
# The replacement should always be a string that may include references to the matched data from the rule.
|
39
|
+
def singular(rule, replacement)
|
40
|
+
@singulars.insert(0, [rule, replacement])
|
41
|
+
end
|
42
|
+
|
43
|
+
# Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used
|
44
|
+
# for strings, not regular expressions. You simply pass the irregular in singular and plural form.
|
45
|
+
#
|
46
|
+
# Examples:
|
47
|
+
# irregular 'octopus', 'octopi'
|
48
|
+
# irregular 'person', 'people'
|
49
|
+
def irregular(singular, plural)
|
50
|
+
plural(Regexp.new("(#{singular[0,1]})#{singular[1..-1]}$", "i"), '\1' + plural[1..-1])
|
51
|
+
singular(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + singular[1..-1])
|
52
|
+
end
|
53
|
+
|
54
|
+
# Add uncountable words that shouldn't be attempted inflected.
|
55
|
+
#
|
56
|
+
# Examples:
|
57
|
+
# uncountable "money"
|
58
|
+
# uncountable "money", "information"
|
59
|
+
# uncountable %w( money information rice )
|
60
|
+
def uncountable(*words)
|
61
|
+
(@uncountables << words).flatten!
|
62
|
+
end
|
63
|
+
|
64
|
+
# Clears the loaded inflections within a given scope (default is :all). Give the scope as a symbol of the inflection type,
|
65
|
+
# the options are: :plurals, :singulars, :uncountables
|
66
|
+
#
|
67
|
+
# Examples:
|
68
|
+
# clear :all
|
69
|
+
# clear :plurals
|
70
|
+
def clear(scope = :all)
|
71
|
+
case scope
|
72
|
+
when :all
|
73
|
+
@plurals, @singulars, @uncountables = [], [], []
|
74
|
+
else
|
75
|
+
instance_variable_set "@#{scope}", []
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
4
80
|
extend self
|
5
81
|
|
82
|
+
def inflections
|
83
|
+
if block_given?
|
84
|
+
yield Inflections.instance
|
85
|
+
else
|
86
|
+
Inflections.instance
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
6
90
|
def pluralize(word)
|
7
91
|
result = word.to_s.dup
|
8
92
|
|
9
|
-
if
|
93
|
+
if inflections.uncountables.include?(result.downcase)
|
10
94
|
result
|
11
95
|
else
|
12
|
-
|
96
|
+
inflections.plurals.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
|
13
97
|
result
|
14
98
|
end
|
15
99
|
end
|
@@ -17,10 +101,10 @@ module Inflector
|
|
17
101
|
def singularize(word)
|
18
102
|
result = word.to_s.dup
|
19
103
|
|
20
|
-
if
|
104
|
+
if inflections.uncountables.include?(result.downcase)
|
21
105
|
result
|
22
106
|
else
|
23
|
-
|
107
|
+
inflections.singulars.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
|
24
108
|
result
|
25
109
|
end
|
26
110
|
end
|
@@ -30,11 +114,11 @@ module Inflector
|
|
30
114
|
end
|
31
115
|
|
32
116
|
def underscore(camel_cased_word)
|
33
|
-
camel_cased_word.to_s.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase
|
117
|
+
camel_cased_word.to_s.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase
|
34
118
|
end
|
35
119
|
|
36
120
|
def humanize(lower_case_and_underscored_word)
|
37
|
-
lower_case_and_underscored_word.to_s.gsub(/_/, " ").capitalize
|
121
|
+
lower_case_and_underscored_word.to_s.gsub(/_id$/, "").gsub(/_/, " ").capitalize
|
38
122
|
end
|
39
123
|
|
40
124
|
def demodulize(class_name_in_module)
|
@@ -50,8 +134,7 @@ module Inflector
|
|
50
134
|
end
|
51
135
|
|
52
136
|
def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
|
53
|
-
|
54
|
-
(separate_class_name_and_id_with_underscore ? "_id" : "id")
|
137
|
+
underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id")
|
55
138
|
end
|
56
139
|
|
57
140
|
def constantize(camel_cased_word)
|
@@ -60,65 +143,18 @@ module Inflector
|
|
60
143
|
end
|
61
144
|
end
|
62
145
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
[/(x|ch|ss|sh)$/i, '\1es'], # search, switch, fix, box, process, address
|
74
|
-
[/([^aeiouy]|qu)ies$/i, '\1y'],
|
75
|
-
[/([^aeiouy]|qu)y$/i, '\1ies'], # query, ability, agency
|
76
|
-
[/(hive)$/i, '\1s'], # archive, hive
|
77
|
-
[/(?:([^f])fe|([lr])f)$/i, '\1\2ves'], # half, safe, wife
|
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)
|
89
|
-
[/$/, 's']
|
90
|
-
]
|
146
|
+
def ordinalize(number)
|
147
|
+
if (11..13).include?(number.to_i % 100)
|
148
|
+
"#{number}th"
|
149
|
+
else
|
150
|
+
case number.to_i % 10
|
151
|
+
when 1: "#{number}st"
|
152
|
+
when 2: "#{number}nd"
|
153
|
+
when 3: "#{number}rd"
|
154
|
+
else "#{number}th"
|
155
|
+
end
|
91
156
|
end
|
157
|
+
end
|
158
|
+
end
|
92
159
|
|
93
|
-
|
94
|
-
[
|
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'],
|
105
|
-
[/(x|ch|ss|sh)es$/i, '\1'],
|
106
|
-
[/(m)ovies$/i, '\1\2ovie'],
|
107
|
-
[/(s)eries$/i, '\1\2eries'],
|
108
|
-
[/([^aeiouy]|qu)ies$/i, '\1y'],
|
109
|
-
[/([lr])ves$/i, '\1f'],
|
110
|
-
[/(tive)s$/i, '\1'],
|
111
|
-
[/(hive)s$/i, '\1'],
|
112
|
-
[/([^f])ves$/i, '\1fe'],
|
113
|
-
[/(^analy)ses$/i, '\1sis'],
|
114
|
-
[/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '\1\2sis'],
|
115
|
-
[/([ti])a$/i, '\1um'],
|
116
|
-
[/(p)eople$/i, '\1\2erson'],
|
117
|
-
[/(m)en$/i, '\1an'],
|
118
|
-
[/(s)tatus$/i, '\1\2tatus'],
|
119
|
-
[/(c)hildren$/i, '\1\2hild'],
|
120
|
-
[/(n)ews$/i, '\1\2ews'],
|
121
|
-
[/s$/i, '']
|
122
|
-
]
|
123
|
-
end
|
124
|
-
end
|
160
|
+
require File.dirname(__FILE__) + '/inflections'
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class OrderedOptions < Array #:nodoc:
|
2
|
+
def []=(key, value)
|
3
|
+
key = key.to_sym
|
4
|
+
|
5
|
+
if pair = find_pair(key)
|
6
|
+
pair.pop
|
7
|
+
pair << value
|
8
|
+
else
|
9
|
+
self << [key, value]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def [](key)
|
14
|
+
pair = find_pair(key.to_sym)
|
15
|
+
pair ? pair.last : nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def method_missing(name, *args)
|
19
|
+
if name.to_s =~ /(.*)=$/
|
20
|
+
self[$1.to_sym] = args.first
|
21
|
+
else
|
22
|
+
self[name]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def find_pair(key)
|
28
|
+
self.each { |i| return i if i.first == key }
|
29
|
+
return false
|
30
|
+
end
|
31
|
+
end
|
@@ -24,23 +24,15 @@ class NilClass
|
|
24
24
|
|
25
25
|
private
|
26
26
|
def method_missing(method, *args, &block)
|
27
|
-
|
28
|
-
raise_nil_warning_for @@method_class_map[method], caller
|
29
|
-
else
|
30
|
-
super
|
31
|
-
end
|
27
|
+
raise_nil_warning_for @@method_class_map[method], method, caller
|
32
28
|
end
|
33
29
|
|
34
|
-
def raise_nil_warning_for(klass, with_caller = nil)
|
35
|
-
|
30
|
+
def raise_nil_warning_for(klass = nil, selector = nil, with_caller = nil)
|
31
|
+
message = "You have a nil object when you didn't expect it!"
|
32
|
+
message << "\nYou might have expected an instance of #{klass}." if klass
|
33
|
+
message << "\nThe error occured while evaluating nil.#{selector}" if selector
|
34
|
+
|
35
|
+
raise NoMethodError, message, with_caller || caller
|
36
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
37
|
end
|
46
38
|
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.10
|
|
3
3
|
specification_version: 1
|
4
4
|
name: activesupport
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.
|
7
|
-
date: 2005-
|
6
|
+
version: 1.2.1
|
7
|
+
date: 2005-10-19
|
8
8
|
summary: Support and utility classes used by the Rails framework.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -38,40 +38,52 @@ files:
|
|
38
38
|
- lib/active_support/core_ext
|
39
39
|
- lib/active_support/core_ext.rb
|
40
40
|
- lib/active_support/dependencies.rb
|
41
|
+
- lib/active_support/inflections.rb
|
41
42
|
- lib/active_support/inflector.rb
|
42
|
-
- lib/active_support/misc.rb
|
43
43
|
- lib/active_support/module_attribute_accessors.rb
|
44
|
+
- lib/active_support/ordered_options.rb
|
44
45
|
- lib/active_support/values
|
46
|
+
- lib/active_support/version.rb
|
45
47
|
- lib/active_support/whiny_nil.rb
|
46
48
|
- lib/active_support/core_ext/array
|
47
49
|
- lib/active_support/core_ext/array.rb
|
50
|
+
- lib/active_support/core_ext/blank.rb
|
48
51
|
- lib/active_support/core_ext/cgi
|
49
52
|
- lib/active_support/core_ext/cgi.rb
|
50
53
|
- lib/active_support/core_ext/date
|
51
54
|
- lib/active_support/core_ext/date.rb
|
52
|
-
- lib/active_support/core_ext/
|
53
|
-
- lib/active_support/core_ext/
|
55
|
+
- lib/active_support/core_ext/enumerable.rb
|
56
|
+
- lib/active_support/core_ext/exception.rb
|
54
57
|
- lib/active_support/core_ext/hash
|
55
58
|
- lib/active_support/core_ext/hash.rb
|
59
|
+
- lib/active_support/core_ext/integer
|
60
|
+
- lib/active_support/core_ext/integer.rb
|
56
61
|
- lib/active_support/core_ext/kernel.rb
|
57
62
|
- lib/active_support/core_ext/load_error.rb
|
58
63
|
- lib/active_support/core_ext/numeric
|
59
64
|
- lib/active_support/core_ext/numeric.rb
|
60
65
|
- lib/active_support/core_ext/object_and_class.rb
|
66
|
+
- lib/active_support/core_ext/range
|
67
|
+
- lib/active_support/core_ext/range.rb
|
61
68
|
- lib/active_support/core_ext/string
|
62
69
|
- lib/active_support/core_ext/string.rb
|
63
70
|
- lib/active_support/core_ext/time
|
64
71
|
- lib/active_support/core_ext/time.rb
|
65
|
-
- lib/active_support/core_ext/array/
|
72
|
+
- lib/active_support/core_ext/array/conversions.rb
|
66
73
|
- lib/active_support/core_ext/cgi/escape_skipping_slashes.rb
|
67
74
|
- lib/active_support/core_ext/date/conversions.rb
|
68
|
-
- lib/active_support/core_ext/fixnum/even_odd.rb
|
69
75
|
- lib/active_support/core_ext/hash/indifferent_access.rb
|
70
76
|
- lib/active_support/core_ext/hash/keys.rb
|
77
|
+
- lib/active_support/core_ext/hash/reverse_merge.rb
|
78
|
+
- lib/active_support/core_ext/integer/even_odd.rb
|
79
|
+
- lib/active_support/core_ext/integer/inflections.rb
|
71
80
|
- lib/active_support/core_ext/numeric/bytes.rb
|
72
81
|
- lib/active_support/core_ext/numeric/time.rb
|
82
|
+
- lib/active_support/core_ext/range/conversions.rb
|
83
|
+
- lib/active_support/core_ext/string/access.rb
|
73
84
|
- lib/active_support/core_ext/string/conversions.rb
|
74
85
|
- lib/active_support/core_ext/string/inflections.rb
|
86
|
+
- lib/active_support/core_ext/string/starts_ends_with.rb
|
75
87
|
- lib/active_support/core_ext/time/calculations.rb
|
76
88
|
- lib/active_support/core_ext/time/conversions.rb
|
77
89
|
- lib/active_support/values/time_zone.rb
|