activesupport 1.4.4 → 2.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 +263 -7
- data/lib/active_support.rb +9 -4
- data/lib/active_support/basic_object.rb +5 -0
- data/lib/active_support/buffered_logger.rb +107 -0
- data/lib/active_support/clean_logger.rb +94 -5
- data/lib/active_support/core_ext.rb +4 -1
- data/lib/active_support/core_ext/array.rb +8 -2
- data/lib/active_support/core_ext/array/access.rb +28 -0
- data/lib/active_support/core_ext/array/conversions.rb +28 -15
- data/lib/active_support/core_ext/array/extract_options.rb +19 -0
- data/lib/active_support/core_ext/array/grouping.rb +20 -7
- data/lib/active_support/core_ext/array/random_access.rb +12 -0
- data/lib/active_support/core_ext/bigdecimal.rb +1 -2
- data/lib/active_support/core_ext/bigdecimal/{formatting.rb → conversions.rb} +1 -2
- data/lib/active_support/core_ext/blank.rb +2 -8
- data/lib/active_support/core_ext/cgi.rb +2 -2
- data/lib/active_support/core_ext/class.rb +4 -3
- data/lib/active_support/core_ext/class/attribute_accessors.rb +1 -1
- data/lib/active_support/core_ext/class/delegating_attributes.rb +40 -0
- data/lib/active_support/core_ext/class/inheritable_attributes.rb +3 -3
- data/lib/active_support/core_ext/class/removal.rb +2 -2
- data/lib/active_support/core_ext/date.rb +5 -1
- data/lib/active_support/core_ext/date/behavior.rb +13 -0
- data/lib/active_support/core_ext/date/calculations.rb +188 -0
- data/lib/active_support/core_ext/date/conversions.rb +69 -13
- data/lib/active_support/core_ext/date_time.rb +10 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +77 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +54 -0
- data/lib/active_support/core_ext/duplicable.rb +37 -0
- data/lib/active_support/core_ext/enumerable.rb +1 -0
- data/lib/active_support/core_ext/exception.rb +2 -2
- data/lib/active_support/core_ext/file.rb +21 -0
- data/lib/active_support/core_ext/float.rb +5 -0
- data/lib/active_support/core_ext/float/rounding.rb +24 -0
- data/lib/active_support/core_ext/hash.rb +5 -5
- data/lib/active_support/core_ext/hash/conversions.rb +86 -34
- data/lib/active_support/core_ext/hash/diff.rb +8 -0
- data/lib/active_support/core_ext/hash/except.rb +24 -0
- data/lib/active_support/core_ext/hash/indifferent_access.rb +15 -2
- data/lib/active_support/core_ext/hash/keys.rb +10 -3
- data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -2
- data/lib/active_support/core_ext/hash/slice.rb +28 -0
- data/lib/active_support/core_ext/integer.rb +2 -2
- data/lib/active_support/core_ext/kernel.rb +5 -4
- data/lib/active_support/core_ext/kernel/debugger.rb +13 -0
- data/lib/active_support/core_ext/module.rb +8 -7
- data/lib/active_support/core_ext/module/aliasing.rb +17 -5
- data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +31 -0
- data/lib/active_support/core_ext/module/attribute_accessors.rb +1 -1
- data/lib/active_support/core_ext/module/delegation.rb +21 -0
- data/lib/active_support/core_ext/name_error.rb +2 -2
- data/lib/active_support/core_ext/numeric.rb +2 -2
- data/lib/active_support/core_ext/numeric/time.rb +30 -11
- data/lib/active_support/core_ext/object.rb +3 -2
- data/lib/active_support/core_ext/object/extending.rb +40 -29
- data/lib/active_support/core_ext/object/instance_variables.rb +22 -0
- data/lib/active_support/core_ext/object/misc.rb +29 -4
- data/lib/active_support/core_ext/pathname.rb +1 -1
- data/lib/active_support/core_ext/range.rb +7 -1
- data/lib/active_support/core_ext/range/blockless_step.rb +22 -0
- data/lib/active_support/core_ext/range/conversions.rb +8 -6
- data/lib/active_support/core_ext/range/include_range.rb +22 -0
- data/lib/active_support/core_ext/range/overlaps.rb +12 -0
- data/lib/active_support/core_ext/string.rb +10 -7
- data/lib/active_support/core_ext/string/conversions.rb +5 -1
- data/lib/active_support/core_ext/string/unicode.rb +2 -2
- data/lib/active_support/core_ext/string/xchar.rb +11 -0
- data/lib/active_support/core_ext/symbol.rb +12 -10
- data/lib/active_support/core_ext/test.rb +1 -0
- data/lib/active_support/core_ext/test/unit/assertions.rb +62 -0
- data/lib/active_support/core_ext/time.rb +4 -2
- data/lib/active_support/core_ext/time/behavior.rb +13 -0
- data/lib/active_support/core_ext/time/calculations.rb +87 -54
- data/lib/active_support/core_ext/time/conversions.rb +71 -10
- data/lib/active_support/dependencies.rb +25 -24
- data/lib/active_support/deprecation.rb +4 -2
- data/lib/active_support/duration.rb +86 -0
- data/lib/active_support/inflections.rb +2 -1
- data/lib/active_support/inflector.rb +13 -6
- data/lib/active_support/json.rb +22 -39
- data/lib/active_support/json/decoding.rb +60 -0
- data/lib/active_support/json/encoders/date.rb +5 -0
- data/lib/active_support/json/encoders/date_time.rb +5 -0
- data/lib/active_support/json/encoders/enumerable.rb +12 -0
- data/lib/active_support/json/encoders/false_class.rb +5 -0
- data/lib/active_support/json/encoders/hash.rb +50 -0
- data/lib/active_support/json/encoders/nil_class.rb +5 -0
- data/lib/active_support/json/encoders/numeric.rb +5 -0
- data/lib/active_support/json/encoders/object.rb +6 -0
- data/lib/active_support/json/encoders/regexp.rb +5 -0
- data/lib/active_support/json/encoders/string.rb +30 -0
- data/lib/active_support/json/encoders/symbol.rb +5 -0
- data/lib/active_support/json/encoders/time.rb +5 -0
- data/lib/active_support/json/encoders/true_class.rb +5 -0
- data/lib/active_support/json/encoding.rb +38 -0
- data/lib/active_support/json/variable.rb +10 -0
- data/lib/active_support/multibyte.rb +7 -5
- data/lib/active_support/multibyte/chars.rb +6 -0
- data/lib/active_support/multibyte/handlers/utf8_handler.rb +115 -5
- data/lib/active_support/option_merger.rb +7 -7
- data/lib/active_support/ordered_options.rb +22 -17
- data/lib/active_support/test_case.rb +5 -0
- data/lib/active_support/testing.rb +1 -0
- data/lib/active_support/testing/default.rb +12 -0
- data/lib/active_support/values/time_zone.rb +3 -3
- data/lib/active_support/vendor.rb +14 -0
- data/lib/active_support/vendor/builder-2.1.2/blankslate.rb +113 -0
- data/lib/active_support/vendor/{builder.rb → builder-2.1.2/builder.rb} +0 -0
- data/lib/active_support/vendor/builder-2.1.2/builder/blankslate.rb +20 -0
- data/lib/active_support/vendor/builder-2.1.2/builder/css.rb +250 -0
- data/lib/active_support/vendor/{builder → builder-2.1.2/builder}/xchar.rb +11 -8
- data/lib/active_support/vendor/{builder → builder-2.1.2/builder}/xmlbase.rb +38 -44
- data/lib/active_support/vendor/{builder → builder-2.1.2/builder}/xmlevents.rb +1 -1
- data/lib/active_support/vendor/{builder → builder-2.1.2/builder}/xmlmarkup.rb +40 -39
- data/lib/active_support/vendor/{xml_simple.rb → xml-simple-1.0.11/xmlsimple.rb} +3 -3
- data/lib/active_support/version.rb +3 -3
- data/lib/active_support/whiny_nil.rb +12 -12
- data/lib/activesupport.rb +1 -0
- metadata +69 -17
- data/lib/active_support/binding_of_caller.rb +0 -84
- data/lib/active_support/breakpoint.rb +0 -528
- data/lib/active_support/caching_tools.rb +0 -62
- data/lib/active_support/json/encoders.rb +0 -25
- data/lib/active_support/json/encoders/core.rb +0 -70
- data/lib/active_support/reloadable.rb +0 -60
- data/lib/active_support/vendor/builder/blankslate.rb +0 -63
@@ -1,10 +1,23 @@
|
|
1
1
|
require 'logger'
|
2
|
-
require
|
2
|
+
require 'active_support/core_ext/class/attribute_accessors'
|
3
3
|
|
4
|
-
|
4
|
+
# Extensions to the built in Ruby logger.
|
5
|
+
#
|
6
|
+
# If you want to use the default log formatter as defined in the Ruby core, then you
|
7
|
+
# will need to set the formatter for the logger as in:
|
8
|
+
#
|
9
|
+
# logger.formatter = Formatter.new
|
10
|
+
#
|
11
|
+
# You can then specify the datetime format, for example:
|
12
|
+
#
|
13
|
+
# logger.datetime_format = "%Y-%m-%d"
|
14
|
+
#
|
15
|
+
# Note: This logger is deprecated in favor of ActiveSupport::BufferedLogger
|
16
|
+
class Logger
|
17
|
+
# Set to false to disable the silencer
|
5
18
|
cattr_accessor :silencer
|
6
19
|
self.silencer = true
|
7
|
-
|
20
|
+
|
8
21
|
# Silences the logger for the duration of the block.
|
9
22
|
def silence(temporary_level = Logger::ERROR)
|
10
23
|
if silencer
|
@@ -18,6 +31,73 @@ class Logger #:nodoc:
|
|
18
31
|
yield self
|
19
32
|
end
|
20
33
|
end
|
34
|
+
|
35
|
+
alias :old_datetime_format= :datetime_format=
|
36
|
+
# Logging date-time format (string passed to +strftime+). Ignored if the formatter
|
37
|
+
# does not respond to datetime_format=.
|
38
|
+
def datetime_format=(datetime_format)
|
39
|
+
formatter.datetime_format = datetime_format if formatter.respond_to?(:datetime_format=)
|
40
|
+
end
|
41
|
+
|
42
|
+
alias :old_datetime_format :datetime_format
|
43
|
+
# Get the logging datetime format. Returns nil if the formatter does not support
|
44
|
+
# datetime formatting.
|
45
|
+
def datetime_format
|
46
|
+
formatter.datetime_format if formatter.respond_to?(:datetime_format)
|
47
|
+
end
|
48
|
+
|
49
|
+
alias :old_formatter :formatter if method_defined?(:formatter)
|
50
|
+
# Get the current formatter. The default formatter is a SimpleFormatter which only
|
51
|
+
# displays the log message
|
52
|
+
def formatter
|
53
|
+
@formatter ||= SimpleFormatter.new
|
54
|
+
end
|
55
|
+
|
56
|
+
unless const_defined? :Formatter
|
57
|
+
class Formatter
|
58
|
+
Format = "%s, [%s#%d] %5s -- %s: %s\n"
|
59
|
+
|
60
|
+
attr_accessor :datetime_format
|
61
|
+
|
62
|
+
def initialize
|
63
|
+
@datetime_format = nil
|
64
|
+
end
|
65
|
+
|
66
|
+
def call(severity, time, progname, msg)
|
67
|
+
Format % [severity[0..0], format_datetime(time), $$, severity, progname,
|
68
|
+
msg2str(msg)]
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
def format_datetime(time)
|
73
|
+
if @datetime_format.nil?
|
74
|
+
time.strftime("%Y-%m-%dT%H:%M:%S.") << "%06d " % time.usec
|
75
|
+
else
|
76
|
+
time.strftime(@datetime_format)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def msg2str(msg)
|
81
|
+
case msg
|
82
|
+
when ::String
|
83
|
+
msg
|
84
|
+
when ::Exception
|
85
|
+
"#{ msg.message } (#{ msg.class })\n" <<
|
86
|
+
(msg.backtrace || []).join("\n")
|
87
|
+
else
|
88
|
+
msg.inspect
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Simple formatter which only displays the message.
|
95
|
+
class SimpleFormatter < Logger::Formatter
|
96
|
+
# This method is invoked when a log event occurs
|
97
|
+
def call(severity, timestamp, progname, msg)
|
98
|
+
"#{String === msg ? msg : msg.inspect}\n"
|
99
|
+
end
|
100
|
+
end
|
21
101
|
|
22
102
|
private
|
23
103
|
alias old_format_message format_message
|
@@ -28,11 +108,20 @@ class Logger #:nodoc:
|
|
28
108
|
# with Logger from 1.8.3 and vice versa.
|
29
109
|
if method_defined?(:formatter=)
|
30
110
|
def format_message(severity, timestamp, progname, msg)
|
31
|
-
|
111
|
+
formatter.call(severity, timestamp, progname, msg)
|
32
112
|
end
|
33
113
|
else
|
34
114
|
def format_message(severity, timestamp, msg, progname)
|
35
|
-
|
115
|
+
formatter.call(severity, timestamp, progname, msg)
|
36
116
|
end
|
117
|
+
|
118
|
+
attr_writer :formatter
|
119
|
+
public :formatter=
|
120
|
+
|
121
|
+
alias old_format_datetime format_datetime
|
122
|
+
def format_datetime(datetime) datetime end
|
123
|
+
|
124
|
+
alias old_msg2str msg2str
|
125
|
+
def msg2str(msg) msg end
|
37
126
|
end
|
38
127
|
end
|
@@ -1,7 +1,13 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'active_support/core_ext/array/access'
|
2
|
+
require 'active_support/core_ext/array/conversions'
|
3
|
+
require 'active_support/core_ext/array/extract_options'
|
4
|
+
require 'active_support/core_ext/array/grouping'
|
5
|
+
require 'active_support/core_ext/array/random_access'
|
3
6
|
|
4
7
|
class Array #:nodoc:
|
8
|
+
include ActiveSupport::CoreExtensions::Array::Access
|
5
9
|
include ActiveSupport::CoreExtensions::Array::Conversions
|
10
|
+
include ActiveSupport::CoreExtensions::Array::ExtractOptions
|
6
11
|
include ActiveSupport::CoreExtensions::Array::Grouping
|
12
|
+
include ActiveSupport::CoreExtensions::Array::RandomAccess
|
7
13
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module ActiveSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module Array #:nodoc:
|
4
|
+
# Makes it easier to access parts of an array.
|
5
|
+
module Access
|
6
|
+
# Returns the remaining of the array from the +position+.
|
7
|
+
#
|
8
|
+
# Examples:
|
9
|
+
# %w( a b c d ).from(0) # => %w( a b c d )
|
10
|
+
# %w( a b c d ).from(2) # => %w( c d )
|
11
|
+
# %w( a b c d ).from(10) # => nil
|
12
|
+
def from(position)
|
13
|
+
self[position..-1]
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns the beginning of the array up to the +position+.
|
17
|
+
#
|
18
|
+
# Examples:
|
19
|
+
# %w( a b c d ).to(0) # => %w( a )
|
20
|
+
# %w( a b c d ).to(2) # => %w( a b c )
|
21
|
+
# %w( a b c d ).to(10) # => %w( a b c d )
|
22
|
+
def to(position)
|
23
|
+
self[0..position]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -1,23 +1,26 @@
|
|
1
|
+
require 'builder'
|
2
|
+
|
1
3
|
module ActiveSupport #:nodoc:
|
2
4
|
module CoreExtensions #:nodoc:
|
3
5
|
module Array #:nodoc:
|
4
6
|
module Conversions
|
5
|
-
# Converts the array to comma-
|
6
|
-
# * <tt>:connector</tt
|
7
|
-
# * <tt>:skip_last_comma</tt
|
7
|
+
# Converts the array to a comma-separated sentence where the last element is joined by the connector word. Options:
|
8
|
+
# * <tt>:connector</tt> - The word used to join the last element in arrays with two or more elements (default: "and")
|
9
|
+
# * <tt>:skip_last_comma</tt> - Set to true to return "a, b and c" instead of "a, b, and c".
|
8
10
|
def to_sentence(options = {})
|
9
11
|
options.assert_valid_keys(:connector, :skip_last_comma)
|
10
12
|
options.reverse_merge! :connector => 'and', :skip_last_comma => false
|
11
|
-
|
13
|
+
options[:connector] = "#{options[:connector]} " unless options[:connector].nil? || options[:connector].strip == ''
|
14
|
+
|
12
15
|
case length
|
13
|
-
|
14
|
-
|
16
|
+
when 0
|
17
|
+
""
|
15
18
|
when 1
|
16
19
|
self[0]
|
17
20
|
when 2
|
18
|
-
"#{self[0]} #{options[:connector]}
|
21
|
+
"#{self[0]} #{options[:connector]}#{self[1]}"
|
19
22
|
else
|
20
|
-
"#{self[0...-1].join(', ')}#{options[:skip_last_comma] ? '' : ','} #{options[:connector]}
|
23
|
+
"#{self[0...-1].join(', ')}#{options[:skip_last_comma] ? '' : ','} #{options[:connector]}#{self[-1]}"
|
21
24
|
end
|
22
25
|
end
|
23
26
|
|
@@ -25,12 +28,14 @@ module ActiveSupport #:nodoc:
|
|
25
28
|
def to_param
|
26
29
|
join '/'
|
27
30
|
end
|
28
|
-
|
29
|
-
def self.included(
|
30
|
-
|
31
|
-
|
31
|
+
|
32
|
+
def self.included(base) #:nodoc:
|
33
|
+
base.class_eval do
|
34
|
+
alias_method :to_default_s, :to_s
|
35
|
+
alias_method :to_s, :to_formatted_s
|
36
|
+
end
|
32
37
|
end
|
33
|
-
|
38
|
+
|
34
39
|
def to_formatted_s(format = :default)
|
35
40
|
case format
|
36
41
|
when :db
|
@@ -43,7 +48,7 @@ module ActiveSupport #:nodoc:
|
|
43
48
|
to_default_s
|
44
49
|
end
|
45
50
|
end
|
46
|
-
|
51
|
+
|
47
52
|
def to_xml(options = {})
|
48
53
|
raise "Not all elements respond to to_xml" unless all? { |e| e.respond_to? :to_xml }
|
49
54
|
|
@@ -63,7 +68,15 @@ module ActiveSupport #:nodoc:
|
|
63
68
|
|
64
69
|
opts = options.merge({ :root => children })
|
65
70
|
|
66
|
-
options[:builder]
|
71
|
+
xml = options[:builder]
|
72
|
+
if empty?
|
73
|
+
xml.tag!(root, options[:skip_types] ? {} : {:type => "array"})
|
74
|
+
else
|
75
|
+
xml.tag!(root, options[:skip_types] ? {} : {:type => "array"}) {
|
76
|
+
yield xml if block_given?
|
77
|
+
each { |e| e.to_xml(opts.merge!({ :skip_instruct => true })) }
|
78
|
+
}
|
79
|
+
end
|
67
80
|
end
|
68
81
|
|
69
82
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ActiveSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module Array #:nodoc:
|
4
|
+
module ExtractOptions
|
5
|
+
# Extract options from a set of arguments. Removes and returns the last element in the array if it's a hash, otherwise returns a blank hash.
|
6
|
+
#
|
7
|
+
# def options(*args)
|
8
|
+
# args.extract_options!
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# options(1, 2) # => {}
|
12
|
+
# options(1, 2, :a => :b) # => {:a=>:b}
|
13
|
+
def extract_options!
|
14
|
+
last.is_a?(::Hash) ? pop : {}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'enumerator'
|
2
|
+
|
1
3
|
module ActiveSupport #:nodoc:
|
2
4
|
module CoreExtensions #:nodoc:
|
3
5
|
module Array #:nodoc:
|
@@ -21,14 +23,23 @@ module ActiveSupport #:nodoc:
|
|
21
23
|
# ["1", "2"]
|
22
24
|
# ["3"]
|
23
25
|
def in_groups_of(number, fill_with = nil, &block)
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
if fill_with == false
|
27
|
+
collection = self
|
28
|
+
else
|
29
|
+
# size % number gives how many extra we have;
|
30
|
+
# subtracting from number gives how many to add;
|
31
|
+
# modulo number ensures we don't add group of just fill.
|
32
|
+
padding = (number - size % number) % number
|
33
|
+
collection = dup.concat([fill_with] * padding)
|
34
|
+
end
|
35
|
+
|
36
|
+
if block_given?
|
37
|
+
collection.each_slice(number, &block)
|
38
|
+
else
|
39
|
+
returning [] do |groups|
|
40
|
+
collection.each_slice(number) { |group| groups << group }
|
41
|
+
end
|
30
42
|
end
|
31
|
-
grouped_collection unless block_given?
|
32
43
|
end
|
33
44
|
|
34
45
|
# Divide the array into one or more subarrays based on a delimiting +value+
|
@@ -40,12 +51,14 @@ module ActiveSupport #:nodoc:
|
|
40
51
|
# (1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]]
|
41
52
|
def split(value = nil, &block)
|
42
53
|
block ||= Proc.new { |e| e == value }
|
54
|
+
|
43
55
|
inject([[]]) do |results, element|
|
44
56
|
if block.call(element)
|
45
57
|
results << []
|
46
58
|
else
|
47
59
|
results.last << element
|
48
60
|
end
|
61
|
+
|
49
62
|
results
|
50
63
|
end
|
51
64
|
end
|
@@ -7,13 +7,7 @@ class Object
|
|
7
7
|
# to
|
8
8
|
# if !address.blank?
|
9
9
|
def blank?
|
10
|
-
|
11
|
-
empty? or strip.empty?
|
12
|
-
elsif respond_to?(:empty?)
|
13
|
-
empty?
|
14
|
-
else
|
15
|
-
!self
|
16
|
-
end
|
10
|
+
respond_to?(:empty?) ? empty? : !self
|
17
11
|
end
|
18
12
|
end
|
19
13
|
|
@@ -45,7 +39,7 @@ end
|
|
45
39
|
|
46
40
|
class String #:nodoc:
|
47
41
|
def blank?
|
48
|
-
|
42
|
+
self !~ /\S/
|
49
43
|
end
|
50
44
|
end
|
51
45
|
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
1
|
+
require 'active_support/core_ext/cgi/escape_skipping_slashes'
|
2
2
|
|
3
3
|
class CGI #:nodoc:
|
4
|
-
extend
|
4
|
+
extend ActiveSupport::CoreExtensions::CGI::EscapeSkippingSlashes
|
5
5
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require 'active_support/core_ext/class/attribute_accessors'
|
2
|
+
require 'active_support/core_ext/class/inheritable_attributes'
|
3
|
+
require 'active_support/core_ext/class/removal'
|
4
|
+
require 'active_support/core_ext/class/delegating_attributes'
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# These class attributes behave something like the class
|
2
|
+
# inheritable accessors. But instead of copying the hash over at
|
3
|
+
# the time the subclass is first defined, the accessors simply
|
4
|
+
# delegate to their superclass unless they have been given a
|
5
|
+
# specific value. This stops the strange situation where values
|
6
|
+
# set after class definition don't get applied to subclasses.
|
7
|
+
class Class
|
8
|
+
def superclass_delegating_reader(*names)
|
9
|
+
class_name_to_stop_searching_on = self.superclass.name.blank? ? "Object" : self.superclass.name
|
10
|
+
names.each do |name|
|
11
|
+
class_eval <<-EOS
|
12
|
+
def self.#{name}
|
13
|
+
if defined?(@#{name})
|
14
|
+
@#{name}
|
15
|
+
elsif superclass < #{class_name_to_stop_searching_on} && superclass.respond_to?(:#{name})
|
16
|
+
superclass.#{name}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
def #{name}
|
20
|
+
self.class.#{name}
|
21
|
+
end
|
22
|
+
EOS
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def superclass_delegating_writer(*names)
|
27
|
+
names.each do |name|
|
28
|
+
class_eval <<-EOS
|
29
|
+
def self.#{name}=(value)
|
30
|
+
@#{name} = value
|
31
|
+
end
|
32
|
+
EOS
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def superclass_delegating_accessor(*names)
|
37
|
+
superclass_delegating_reader(*names)
|
38
|
+
superclass_delegating_writer(*names)
|
39
|
+
end
|
40
|
+
end
|