activesupport 1.0.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 +70 -0
- data/lib/active_support.rb +31 -0
- data/lib/active_support/binding_of_caller.rb +84 -0
- data/lib/active_support/breakpoint.rb +523 -0
- data/lib/active_support/class_attribute_accessors.rb +57 -0
- data/lib/active_support/class_inheritable_attributes.rb +117 -0
- data/lib/active_support/clean_logger.rb +10 -0
- data/lib/active_support/core_ext.rb +1 -0
- data/lib/active_support/core_ext/date.rb +6 -0
- data/lib/active_support/core_ext/date/conversions.rb +31 -0
- data/lib/active_support/core_ext/hash.rb +7 -0
- data/lib/active_support/core_ext/hash/indifferent_access.rb +38 -0
- data/lib/active_support/core_ext/hash/keys.rb +53 -0
- data/lib/active_support/core_ext/numeric.rb +7 -0
- data/lib/active_support/core_ext/numeric/bytes.rb +33 -0
- data/lib/active_support/core_ext/numeric/time.rb +59 -0
- data/lib/active_support/core_ext/object_and_class.rb +24 -0
- data/lib/active_support/core_ext/string.rb +5 -0
- data/lib/active_support/core_ext/string/inflections.rb +49 -0
- data/lib/active_support/core_ext/time.rb +7 -0
- data/lib/active_support/core_ext/time/calculations.rb +133 -0
- data/lib/active_support/core_ext/time/conversions.rb +34 -0
- data/lib/active_support/dependencies.rb +212 -0
- data/lib/active_support/inflector.rb +93 -0
- data/lib/active_support/misc.rb +8 -0
- data/lib/active_support/module_attribute_accessors.rb +57 -0
- data/lib/active_support/values/time_zone.rb +180 -0
- metadata +71 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
# Extends the class object with class and instance accessors for class attributes,
|
2
|
+
# just like the native attr* accessors for instance attributes.
|
3
|
+
class Class # :nodoc:
|
4
|
+
def cattr_reader(*syms)
|
5
|
+
syms.each do |sym|
|
6
|
+
class_eval <<-EOS
|
7
|
+
if ! defined? @@#{sym.id2name}
|
8
|
+
@@#{sym.id2name} = nil
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.#{sym.id2name}
|
12
|
+
@@#{sym}
|
13
|
+
end
|
14
|
+
|
15
|
+
def #{sym.id2name}
|
16
|
+
@@#{sym}
|
17
|
+
end
|
18
|
+
|
19
|
+
def call_#{sym.id2name}
|
20
|
+
case @@#{sym.id2name}
|
21
|
+
when Symbol then send(@@#{sym})
|
22
|
+
when Proc then @@#{sym}.call(self)
|
23
|
+
when String then @@#{sym}
|
24
|
+
else nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
EOS
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def cattr_writer(*syms)
|
32
|
+
syms.each do |sym|
|
33
|
+
class_eval <<-EOS
|
34
|
+
if ! defined? @@#{sym.id2name}
|
35
|
+
@@#{sym.id2name} = nil
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.#{sym.id2name}=(obj)
|
39
|
+
@@#{sym.id2name} = obj
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.set_#{sym.id2name}(obj)
|
43
|
+
@@#{sym.id2name} = obj
|
44
|
+
end
|
45
|
+
|
46
|
+
def #{sym.id2name}=(obj)
|
47
|
+
@@#{sym} = obj
|
48
|
+
end
|
49
|
+
EOS
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def cattr_accessor(*syms)
|
54
|
+
cattr_reader(*syms)
|
55
|
+
cattr_writer(*syms)
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# Retain for backward compatibility. Methods are now included in Class.
|
2
|
+
module ClassInheritableAttributes # :nodoc:
|
3
|
+
end
|
4
|
+
|
5
|
+
# Allows attributes to be shared within an inheritance hierarchy, but where each descendant gets a copy of
|
6
|
+
# their parents' attributes, instead of just a pointer to the same. This means that the child can add elements
|
7
|
+
# to, for example, an array without those additions being shared with either their parent, siblings, or
|
8
|
+
# children, which is unlike the regular class-level attributes that are shared across the entire hierarchy.
|
9
|
+
class Class # :nodoc:
|
10
|
+
def class_inheritable_reader(*syms)
|
11
|
+
syms.each do |sym|
|
12
|
+
class_eval <<-EOS
|
13
|
+
def self.#{sym}
|
14
|
+
read_inheritable_attribute(:#{sym})
|
15
|
+
end
|
16
|
+
|
17
|
+
def #{sym}
|
18
|
+
self.class.#{sym}
|
19
|
+
end
|
20
|
+
EOS
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def class_inheritable_writer(*syms)
|
25
|
+
syms.each do |sym|
|
26
|
+
class_eval <<-EOS
|
27
|
+
def self.#{sym}=(obj)
|
28
|
+
write_inheritable_attribute(:#{sym}, obj)
|
29
|
+
end
|
30
|
+
|
31
|
+
def #{sym}=(obj)
|
32
|
+
self.class.#{sym} = obj
|
33
|
+
end
|
34
|
+
EOS
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def class_inheritable_array_writer(*syms)
|
39
|
+
syms.each do |sym|
|
40
|
+
class_eval <<-EOS
|
41
|
+
def self.#{sym}=(obj)
|
42
|
+
write_inheritable_array(:#{sym}, obj)
|
43
|
+
end
|
44
|
+
|
45
|
+
def #{sym}=(obj)
|
46
|
+
self.class.#{sym} = obj
|
47
|
+
end
|
48
|
+
EOS
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def class_inheritable_hash_writer(*syms)
|
53
|
+
syms.each do |sym|
|
54
|
+
class_eval <<-EOS
|
55
|
+
def self.#{sym}=(obj)
|
56
|
+
write_inheritable_hash(:#{sym}, obj)
|
57
|
+
end
|
58
|
+
|
59
|
+
def #{sym}=(obj)
|
60
|
+
self.class.#{sym} = obj
|
61
|
+
end
|
62
|
+
EOS
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def class_inheritable_accessor(*syms)
|
67
|
+
class_inheritable_reader(*syms)
|
68
|
+
class_inheritable_writer(*syms)
|
69
|
+
end
|
70
|
+
|
71
|
+
def class_inheritable_array(*syms)
|
72
|
+
class_inheritable_reader(*syms)
|
73
|
+
class_inheritable_array_writer(*syms)
|
74
|
+
end
|
75
|
+
|
76
|
+
def class_inheritable_hash(*syms)
|
77
|
+
class_inheritable_reader(*syms)
|
78
|
+
class_inheritable_hash_writer(*syms)
|
79
|
+
end
|
80
|
+
|
81
|
+
def inheritable_attributes
|
82
|
+
@inheritable_attributes ||= {}
|
83
|
+
end
|
84
|
+
|
85
|
+
def write_inheritable_attribute(key, value)
|
86
|
+
inheritable_attributes[key] = value
|
87
|
+
end
|
88
|
+
|
89
|
+
def write_inheritable_array(key, elements)
|
90
|
+
write_inheritable_attribute(key, []) if read_inheritable_attribute(key).nil?
|
91
|
+
write_inheritable_attribute(key, read_inheritable_attribute(key) + elements)
|
92
|
+
end
|
93
|
+
|
94
|
+
def write_inheritable_hash(key, hash)
|
95
|
+
write_inheritable_attribute(key, {}) if read_inheritable_attribute(key).nil?
|
96
|
+
write_inheritable_attribute(key, read_inheritable_attribute(key).merge(hash))
|
97
|
+
end
|
98
|
+
|
99
|
+
def read_inheritable_attribute(key)
|
100
|
+
inheritable_attributes[key]
|
101
|
+
end
|
102
|
+
|
103
|
+
def reset_inheritable_attributes
|
104
|
+
inheritable_attributes.clear
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
def inherited_with_inheritable_attributes(child)
|
109
|
+
inherited_without_inheritable_attributes(child) if respond_to?(:inherited_without_inheritable_attributes)
|
110
|
+
child.instance_variable_set('@inheritable_attributes', inheritable_attributes.dup)
|
111
|
+
end
|
112
|
+
|
113
|
+
if respond_to?(:inherited)
|
114
|
+
alias_method :inherited_without_inheritable_attributes, :inherited
|
115
|
+
end
|
116
|
+
alias_method :inherited, :inherited_with_inheritable_attributes
|
117
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Dir[File.dirname(__FILE__) + "/core_ext/*.rb"].each { |file| require(file) }
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module ActiveSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module Date #:nodoc:
|
4
|
+
# Getting dates in different convenient string representations and other objects
|
5
|
+
module Conversions
|
6
|
+
def self.append_features(klass) #:nodoc:
|
7
|
+
super
|
8
|
+
klass.send(:alias_method, :to_default_s, :to_s)
|
9
|
+
klass.send(:alias_method, :to_s, :to_formatted_s)
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_formatted_s(format = :default)
|
13
|
+
case format
|
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
|
+
end
|
19
|
+
|
20
|
+
# To be able to keep Dates and Times interchangeable on conversions
|
21
|
+
def to_date
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_time(form = :local)
|
26
|
+
::Time.send(form, year, month, day)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class HashWithIndifferentAccess < Hash
|
2
|
+
def initialize(constructor)
|
3
|
+
if constructor.is_a?(Hash)
|
4
|
+
super()
|
5
|
+
update(constructor.symbolize_keys)
|
6
|
+
else
|
7
|
+
super(constructor)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
alias_method :regular_reader, :[] unless method_defined?(:regular_reader)
|
12
|
+
|
13
|
+
def [](key)
|
14
|
+
case key
|
15
|
+
when Symbol: regular_reader(key) || regular_reader(key.to_s)
|
16
|
+
when String: regular_reader(key) || regular_reader(key.to_sym)
|
17
|
+
else regular_reader(key)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
|
22
|
+
|
23
|
+
def []=(key, value)
|
24
|
+
regular_writer(key.is_a?(String) ? key.to_sym : key, value)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module ActiveSupport #:nodoc:
|
29
|
+
module CoreExtensions #:nodoc:
|
30
|
+
module Hash #:nodoc:
|
31
|
+
module IndifferentAccess
|
32
|
+
def with_indifferent_access
|
33
|
+
HashWithIndifferentAccess.new(self)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module ActiveSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module Hash #:nodoc:
|
4
|
+
module Keys
|
5
|
+
# Return a new hash with all keys converted to strings.
|
6
|
+
def stringify_keys
|
7
|
+
inject({}) do |options, (key, value)|
|
8
|
+
options[key.to_s] = value
|
9
|
+
options
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Destructively convert all keys to strings.
|
14
|
+
def stringify_keys!
|
15
|
+
keys.each do |key|
|
16
|
+
unless key.class.to_s == "String" # weird hack to make the tests run when string_ext_test.rb is also running
|
17
|
+
self[key.to_s] = self[key]
|
18
|
+
delete(key)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
# Return a new hash with all keys converted to symbols.
|
25
|
+
def symbolize_keys
|
26
|
+
inject({}) do |options, (key, value)|
|
27
|
+
options[key.to_sym] = value
|
28
|
+
options
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Destructively convert all keys to symbols.
|
33
|
+
def symbolize_keys!
|
34
|
+
keys.each do |key|
|
35
|
+
unless key.is_a?(Symbol)
|
36
|
+
self[key.to_sym] = self[key]
|
37
|
+
delete(key)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
alias_method :to_options, :symbolize_keys
|
44
|
+
alias_method :to_options!, :symbolize_keys!
|
45
|
+
|
46
|
+
def assert_valid_keys(valid_keys)
|
47
|
+
unknown_keys = keys - valid_keys
|
48
|
+
raise(ArgumentError, "Unknown key(s): #{unknown_keys.join(", ")}") unless unknown_keys.empty?
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module ActiveSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module Numeric #:nodoc:
|
4
|
+
# Enables the use of byte calculations and declarations, like 45.bytes + 2.6.megabytes
|
5
|
+
module Bytes
|
6
|
+
def bytes
|
7
|
+
self
|
8
|
+
end
|
9
|
+
alias :byte :bytes
|
10
|
+
|
11
|
+
def kilobytes
|
12
|
+
self * 1024
|
13
|
+
end
|
14
|
+
alias :kilobyte :kilobytes
|
15
|
+
|
16
|
+
def megabytes
|
17
|
+
self * 1024.kilobytes
|
18
|
+
end
|
19
|
+
alias :megabyte :megabytes
|
20
|
+
|
21
|
+
def gigabytes
|
22
|
+
self * 1024.megabytes
|
23
|
+
end
|
24
|
+
alias :gigabyte :gigabytes
|
25
|
+
|
26
|
+
def terabytes
|
27
|
+
self * 1024.gigabytes
|
28
|
+
end
|
29
|
+
alias :terabyte :terabytes
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module ActiveSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module Numeric #:nodoc:
|
4
|
+
# Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years
|
5
|
+
module Time
|
6
|
+
def minutes
|
7
|
+
self * 60
|
8
|
+
end
|
9
|
+
alias :minute :minutes
|
10
|
+
|
11
|
+
def hours
|
12
|
+
self * 60.minutes
|
13
|
+
end
|
14
|
+
alias :hour :hours
|
15
|
+
|
16
|
+
def days
|
17
|
+
self * 24.hours
|
18
|
+
end
|
19
|
+
alias :day :days
|
20
|
+
|
21
|
+
def weeks
|
22
|
+
self * 7.days
|
23
|
+
end
|
24
|
+
alias :week :weeks
|
25
|
+
|
26
|
+
def fortnights
|
27
|
+
self * 2.weeks
|
28
|
+
end
|
29
|
+
alias :fortnight :fortnights
|
30
|
+
|
31
|
+
def months
|
32
|
+
self * 30.days
|
33
|
+
end
|
34
|
+
alias :month :months
|
35
|
+
|
36
|
+
def years
|
37
|
+
self * 365.days
|
38
|
+
end
|
39
|
+
alias :year :years
|
40
|
+
|
41
|
+
# Reads best without arguments: 10.minutes.ago
|
42
|
+
def ago(time = ::Time.now)
|
43
|
+
time - self
|
44
|
+
end
|
45
|
+
|
46
|
+
# Reads best with argument: 10.minutes.until(time)
|
47
|
+
alias :until :ago
|
48
|
+
|
49
|
+
# Reads best with argument: 10.minutes.since(time)
|
50
|
+
def since(time = ::Time.now)
|
51
|
+
time + self
|
52
|
+
end
|
53
|
+
|
54
|
+
# Reads best without arguments: 10.minutes.from_now
|
55
|
+
alias :from_now :since
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class Object #:nodoc:
|
2
|
+
def remove_subclasses_of(superclass)
|
3
|
+
subclasses_of(superclass).each { |subclass| Object.send(:remove_const, subclass) rescue nil }
|
4
|
+
end
|
5
|
+
|
6
|
+
def subclasses_of(superclass)
|
7
|
+
subclasses = []
|
8
|
+
ObjectSpace.each_object(Class) do |k|
|
9
|
+
next if !k.ancestors.include?(superclass) || superclass == k || k.to_s.include?("::") || subclasses.include?(k.to_s)
|
10
|
+
subclasses << k.to_s
|
11
|
+
end
|
12
|
+
subclasses
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class Class #:nodoc:
|
17
|
+
def remove_subclasses
|
18
|
+
Object.remove_subclasses_of(self)
|
19
|
+
end
|
20
|
+
|
21
|
+
def subclasses
|
22
|
+
Object.subclasses_of(self)
|
23
|
+
end
|
24
|
+
end
|