activesupport 3.0.0.rc → 3.0.0.rc2
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 -37
- data/lib/active_support/base64.rb +3 -3
- data/lib/active_support/benchmarkable.rb +3 -3
- data/lib/active_support/cache.rb +46 -56
- data/lib/active_support/cache/mem_cache_store.rb +3 -4
- data/lib/active_support/cache/memory_store.rb +5 -5
- data/lib/active_support/cache/strategy/local_cache.rb +5 -5
- data/lib/active_support/callbacks.rb +13 -3
- data/lib/active_support/concern.rb +35 -0
- data/lib/active_support/configurable.rb +2 -2
- data/lib/active_support/core_ext/array/conversions.rb +6 -6
- data/lib/active_support/core_ext/array/random_access.rb +4 -4
- data/lib/active_support/core_ext/array/uniq_by.rb +1 -1
- data/lib/active_support/core_ext/array/wrap.rb +30 -4
- data/lib/active_support/core_ext/class/attribute.rb +27 -4
- data/lib/active_support/core_ext/class/attribute_accessors.rb +16 -0
- data/lib/active_support/core_ext/class/inheritable_attributes.rb +25 -3
- data/lib/active_support/core_ext/date/calculations.rb +15 -15
- data/lib/active_support/core_ext/date_time/conversions.rb +6 -6
- data/lib/active_support/core_ext/date_time/zones.rb +1 -1
- data/lib/active_support/core_ext/enumerable.rb +6 -5
- data/lib/active_support/core_ext/hash/conversions.rb +11 -11
- data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -3
- data/lib/active_support/core_ext/integer/time.rb +2 -2
- data/lib/active_support/core_ext/kernel/reporting.rb +1 -1
- data/lib/active_support/core_ext/module/anonymous.rb +1 -1
- data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +2 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +1 -1
- data/lib/active_support/core_ext/module/remove_method.rb +1 -1
- data/lib/active_support/core_ext/module/synchronization.rb +2 -2
- data/lib/active_support/core_ext/numeric/time.rb +9 -9
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/object/blank.rb +1 -1
- data/lib/active_support/core_ext/object/instance_variables.rb +5 -5
- data/lib/active_support/core_ext/object/returning.rb +43 -0
- data/lib/active_support/core_ext/range/conversions.rb +1 -1
- data/lib/active_support/core_ext/string/access.rb +7 -7
- data/lib/active_support/core_ext/string/inflections.rb +8 -6
- data/lib/active_support/core_ext/string/multibyte.rb +5 -5
- data/lib/active_support/core_ext/time/calculations.rb +2 -2
- data/lib/active_support/core_ext/time/conversions.rb +1 -1
- data/lib/active_support/core_ext/time/zones.rb +3 -3
- data/lib/active_support/dependencies.rb +56 -38
- data/lib/active_support/duration.rb +1 -1
- data/lib/active_support/hash_with_indifferent_access.rb +9 -3
- data/lib/active_support/i18n_railtie.rb +1 -1
- data/lib/active_support/lazy_load_hooks.rb +20 -1
- data/lib/active_support/locale/en.yml +3 -3
- data/lib/active_support/log_subscriber.rb +32 -33
- data/lib/active_support/log_subscriber/test_helper.rb +1 -1
- data/lib/active_support/message_encryptor.rb +17 -17
- data/lib/active_support/message_verifier.rb +7 -7
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/multibyte/chars.rb +37 -36
- data/lib/active_support/multibyte/unicode.rb +4 -4
- data/lib/active_support/notifications.rb +3 -3
- data/lib/active_support/secure_random.rb +13 -13
- data/lib/active_support/testing/assertions.rb +8 -6
- data/lib/active_support/testing/declarative.rb +4 -4
- data/lib/active_support/testing/isolation.rb +1 -1
- data/lib/active_support/testing/pending.rb +3 -3
- data/lib/active_support/testing/performance.rb +9 -5
- data/lib/active_support/time_with_zone.rb +2 -2
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/nokogiri.rb +6 -1
- data/lib/active_support/xml_mini/nokogirisax.rb +7 -2
- data/lib/active_support/xml_mini/rexml.rb +1 -1
- metadata +5 -4
@@ -16,8 +16,7 @@ module ActiveSupport
|
|
16
16
|
# Special features:
|
17
17
|
# - Clustering and load balancing. One can specify multiple memcached servers,
|
18
18
|
# and MemCacheStore will load balance between all available servers. If a
|
19
|
-
# server goes down, then MemCacheStore will ignore it until it
|
20
|
-
# online.
|
19
|
+
# server goes down, then MemCacheStore will ignore it until it comes back up.
|
21
20
|
#
|
22
21
|
# MemCacheStore implements the Strategy::LocalCache strategy which implements
|
23
22
|
# an in memory cache inside of a block.
|
@@ -69,7 +68,7 @@ module ActiveSupport
|
|
69
68
|
extend LocalCacheWithRaw
|
70
69
|
end
|
71
70
|
|
72
|
-
# Reads multiple
|
71
|
+
# Reads multiple values from the cache using a single call to the
|
73
72
|
# servers for all keys. Options can be passed in the last argument.
|
74
73
|
def read_multi(*names)
|
75
74
|
options = names.extract_options!
|
@@ -113,7 +112,7 @@ module ActiveSupport
|
|
113
112
|
end
|
114
113
|
|
115
114
|
# Clear the entire cache on all memcached servers. This method should
|
116
|
-
# be used with care when
|
115
|
+
# be used with care when shared cache is being used.
|
117
116
|
def clear(options = nil)
|
118
117
|
@data.flush_all
|
119
118
|
end
|
@@ -5,9 +5,9 @@ module ActiveSupport
|
|
5
5
|
# A cache store implementation which stores everything into memory in the
|
6
6
|
# same process. If you're running multiple Ruby on Rails server processes
|
7
7
|
# (which is the case if you're using mongrel_cluster or Phusion Passenger),
|
8
|
-
# then this means that
|
8
|
+
# then this means that Rails server process instances won't be able
|
9
9
|
# to share cache data with each other and this may not be the most
|
10
|
-
# appropriate cache
|
10
|
+
# appropriate cache in that scenario.
|
11
11
|
#
|
12
12
|
# This cache has a bounded size specified by the :size options to the
|
13
13
|
# initializer (default is 32Mb). When the cache exceeds the allotted size,
|
@@ -47,8 +47,8 @@ module ActiveSupport
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
#
|
51
|
-
#
|
50
|
+
# To ensure entries fit within the specified memory prune the cache by removing the least
|
51
|
+
# recently accessed entries.
|
52
52
|
def prune(target_size, max_time = nil)
|
53
53
|
return if pruning?
|
54
54
|
@pruning = true
|
@@ -67,7 +67,7 @@ module ActiveSupport
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
-
#
|
70
|
+
# Returns true if the cache is currently being pruned.
|
71
71
|
def pruning?
|
72
72
|
@pruning
|
73
73
|
end
|
@@ -8,7 +8,7 @@ module ActiveSupport
|
|
8
8
|
# duration of a block. Repeated calls to the cache for the same key will hit the
|
9
9
|
# in memory cache for faster access.
|
10
10
|
module LocalCache
|
11
|
-
# Simple memory backed cache. This cache is not thread safe
|
11
|
+
# Simple memory backed cache. This cache is not thread safe and is intended only
|
12
12
|
# for serving as a temporary memory cache for a single thread.
|
13
13
|
class LocalStore < Store
|
14
14
|
def initialize
|
@@ -16,7 +16,7 @@ module ActiveSupport
|
|
16
16
|
@data = {}
|
17
17
|
end
|
18
18
|
|
19
|
-
#
|
19
|
+
# Don't allow synchronizing since it isn't thread safe,
|
20
20
|
def synchronize # :nodoc:
|
21
21
|
yield
|
22
22
|
end
|
@@ -39,7 +39,7 @@ module ActiveSupport
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
# Use a local cache
|
42
|
+
# Use a local cache for the duration of block.
|
43
43
|
def with_local_cache
|
44
44
|
save_val = Thread.current[thread_local_key]
|
45
45
|
begin
|
@@ -50,8 +50,8 @@ module ActiveSupport
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
-
# Middleware class can be inserted as a Rack handler to
|
54
|
-
# duration of
|
53
|
+
# Middleware class can be inserted as a Rack handler to be local cache for the
|
54
|
+
# duration of request.
|
55
55
|
def middleware
|
56
56
|
@middleware ||= begin
|
57
57
|
klass = Class.new
|
@@ -93,6 +93,11 @@ module ActiveSupport
|
|
93
93
|
send("_run_#{kind}_callbacks", *args, &block)
|
94
94
|
end
|
95
95
|
|
96
|
+
def callback(kind)
|
97
|
+
ActiveSupport::Deprecation.warn("callback is deprecated. Please use run_callbacks")
|
98
|
+
send("_run_#{kind}_callbacks")
|
99
|
+
end
|
100
|
+
|
96
101
|
class Callback
|
97
102
|
@@_callback_sequence = 0
|
98
103
|
|
@@ -419,7 +424,10 @@ module ActiveSupport
|
|
419
424
|
@_keyed_callbacks ||= {}
|
420
425
|
@_keyed_callbacks[name] ||= begin
|
421
426
|
str = send("_#{kind}_callbacks").compile(name, object)
|
422
|
-
class_eval
|
427
|
+
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
428
|
+
def #{name}() #{str} end
|
429
|
+
protected :#{name}
|
430
|
+
RUBY_EVAL
|
423
431
|
true
|
424
432
|
end
|
425
433
|
end
|
@@ -476,7 +484,7 @@ module ActiveSupport
|
|
476
484
|
end
|
477
485
|
|
478
486
|
filters.each do |filter|
|
479
|
-
chain.delete_if {|c| c.matches?(type, filter) }
|
487
|
+
chain.delete_if {|c| c.matches?(type, filter) }
|
480
488
|
end
|
481
489
|
|
482
490
|
options[:prepend] ? chain.unshift(*mapped) : chain.push(*mapped)
|
@@ -568,7 +576,9 @@ module ActiveSupport
|
|
568
576
|
#
|
569
577
|
# would trigger <tt>Audit#before_save</tt> instead. That's constructed by calling
|
570
578
|
# <tt>"#{kind}_#{name}"</tt> on the given instance. In this case "kind" is "before" and
|
571
|
-
# "name" is "save".
|
579
|
+
# "name" is "save". In this context ":kind" and ":name" have special meanings: ":kind"
|
580
|
+
# refers to the kind of callback (before/after/around) and ":name" refers to the
|
581
|
+
# method on which callbacks are being defined.
|
572
582
|
#
|
573
583
|
# A declaration like
|
574
584
|
#
|
@@ -1,3 +1,38 @@
|
|
1
|
+
# A typical module looks like this
|
2
|
+
#
|
3
|
+
# module M
|
4
|
+
# def self.included(base)
|
5
|
+
# base.send(:extend, ClassMethods)
|
6
|
+
# base.send(:include, InstanceMethods)
|
7
|
+
# scope :foo, :conditions => { :created_at => nil }
|
8
|
+
# end
|
9
|
+
#
|
10
|
+
# module ClassMethods
|
11
|
+
# def cm; puts 'I am a class method'; end
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# module InstanceMethods
|
15
|
+
# def im; puts 'I am an instance method'; end
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# By using <tt>ActiveSupport::Concern</tt> the above module could instead be written as:
|
20
|
+
#
|
21
|
+
# module M
|
22
|
+
# extend ActiveSupport::Concern
|
23
|
+
#
|
24
|
+
# included do
|
25
|
+
# scope :foo, :conditions => { :created_at => nil }
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# module ClassMethods
|
29
|
+
# def cm; puts 'I am a class method'; end
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# module InstanceMethods
|
33
|
+
# def im; puts 'I am an instance method'; end
|
34
|
+
# end
|
35
|
+
# end
|
1
36
|
module ActiveSupport
|
2
37
|
module Concern
|
3
38
|
def self.extended(base)
|
@@ -9,7 +9,7 @@ module ActiveSupport
|
|
9
9
|
|
10
10
|
module ClassMethods
|
11
11
|
def config
|
12
|
-
@
|
12
|
+
@_config ||= ActiveSupport::InheritableOptions.new(superclass.respond_to?(:config) ? superclass.config : {})
|
13
13
|
end
|
14
14
|
|
15
15
|
def configure
|
@@ -30,7 +30,7 @@ module ActiveSupport
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def config
|
33
|
-
@
|
33
|
+
@_config ||= ActiveSupport::InheritableOptions.new(self.class.config)
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
@@ -26,7 +26,7 @@ class Array
|
|
26
26
|
when 0
|
27
27
|
""
|
28
28
|
when 1
|
29
|
-
self[0].to_s
|
29
|
+
self[0].to_s.dup
|
30
30
|
when 2
|
31
31
|
"#{self[0]}#{options[:two_words_connector]}#{self[1]}"
|
32
32
|
else
|
@@ -58,12 +58,12 @@ class Array
|
|
58
58
|
alias_method :to_default_s, :to_s
|
59
59
|
alias_method :to_s, :to_formatted_s
|
60
60
|
|
61
|
-
# Returns a string that represents
|
62
|
-
#
|
61
|
+
# Returns a string that represents the array in XML by invoking +to_xml+
|
62
|
+
# on each element. Active Record collections delegate their representation
|
63
63
|
# in XML to this method.
|
64
64
|
#
|
65
65
|
# All elements are expected to respond to +to_xml+, if any of them does
|
66
|
-
# not an exception is raised.
|
66
|
+
# not then an exception is raised.
|
67
67
|
#
|
68
68
|
# The root node reflects the class name of the first element in plural
|
69
69
|
# if all elements belong to the same type and that's not Hash:
|
@@ -115,8 +115,8 @@ class Array
|
|
115
115
|
# <?xml version="1.0" encoding="UTF-8"?>
|
116
116
|
# <projects type="array"/>
|
117
117
|
#
|
118
|
-
# By default
|
119
|
-
#
|
118
|
+
# By default name of the node for the children of root is <tt>root.singularize</tt>.
|
119
|
+
# You can change it with the <tt>:children</tt> option.
|
120
120
|
#
|
121
121
|
# The +options+ hash is passed downwards:
|
122
122
|
#
|
@@ -1,10 +1,10 @@
|
|
1
1
|
class Array
|
2
2
|
# Backport of Array#sample based on Marc-Andre Lafortune's http://github.com/marcandre/backports/
|
3
|
-
# Returns a random element or +n+ random elements from the array.
|
3
|
+
# Returns a random element or +n+ random elements from the array.
|
4
4
|
# If the array is empty and +n+ is nil, returns <tt>nil</tt>. if +n+ is passed, returns <tt>[]</tt>.
|
5
|
-
#
|
6
|
-
# [1,2,3,4,5,6].sample # => 4
|
7
|
-
# [1,2,3,4,5,6].sample(3) # => [2, 4, 5]
|
5
|
+
#
|
6
|
+
# [1,2,3,4,5,6].sample # => 4
|
7
|
+
# [1,2,3,4,5,6].sample(3) # => [2, 4, 5]
|
8
8
|
# [].sample # => nil
|
9
9
|
# [].sample(3) # => []
|
10
10
|
def sample(n=nil)
|
@@ -1,15 +1,41 @@
|
|
1
1
|
class Array
|
2
|
-
# Wraps
|
3
|
-
# object to an Array using #to_ary if it implements that.
|
2
|
+
# Wraps its argument in an array unless it is already an array (or array-like).
|
4
3
|
#
|
5
|
-
#
|
6
|
-
#
|
4
|
+
# Specifically:
|
5
|
+
#
|
6
|
+
# * If the argument is +nil+ an empty list is returned.
|
7
|
+
# * Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned.
|
8
|
+
# * Otherwise, returns an array with the argument as its single element.
|
9
|
+
#
|
10
|
+
# Array.wrap(nil) # => []
|
11
|
+
# Array.wrap([1, 2, 3]) # => [1, 2, 3]
|
12
|
+
# Array.wrap(0) # => [0]
|
13
|
+
#
|
14
|
+
# This method is similar in purpose to <tt>Kernel#Array</tt>, but there are some differences:
|
15
|
+
#
|
16
|
+
# * If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt>
|
17
|
+
# moves on to try +to_a+ if the returned value is +nil+, but <tt>Arraw.wrap</tt> returns
|
18
|
+
# such a +nil+ right away.
|
19
|
+
# * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt>
|
20
|
+
# raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value.
|
21
|
+
# * It does not call +to_a+ on the argument, though special-cases +nil+ to return an empty array.
|
22
|
+
#
|
23
|
+
# The last point is particularly worth comparing for some enumerables:
|
7
24
|
#
|
8
25
|
# Array(:foo => :bar) # => [[:foo, :bar]]
|
9
26
|
# Array.wrap(:foo => :bar) # => [{:foo => :bar}]
|
10
27
|
#
|
11
28
|
# Array("foo\nbar") # => ["foo\n", "bar"], in Ruby 1.8
|
12
29
|
# Array.wrap("foo\nbar") # => ["foo\nbar"]
|
30
|
+
#
|
31
|
+
# There's also a related idiom that uses the splat operator:
|
32
|
+
#
|
33
|
+
# [*object]
|
34
|
+
#
|
35
|
+
# which returns <tt>[nil]</tt> for +nil+, and calls to <tt>Array(object)</tt> otherwise.
|
36
|
+
#
|
37
|
+
# Thus, in this case the behavior is different for +nil+, and the differences with
|
38
|
+
# <tt>Kernel#Array</tt> explained above apply to the rest of +object+s.
|
13
39
|
def self.wrap(object)
|
14
40
|
if object.nil?
|
15
41
|
[]
|
@@ -2,8 +2,8 @@ require 'active_support/core_ext/kernel/singleton_class'
|
|
2
2
|
require 'active_support/core_ext/module/remove_method'
|
3
3
|
|
4
4
|
class Class
|
5
|
-
# Declare a class-level attribute whose value is inheritable
|
6
|
-
#
|
5
|
+
# Declare a class-level attribute whose value is inheritable by subclasses.
|
6
|
+
# Subclasses can change their own value and it will not impact parent class.
|
7
7
|
#
|
8
8
|
# class Base
|
9
9
|
# class_attribute :setting
|
@@ -18,12 +18,34 @@ class Class
|
|
18
18
|
# Subclass.setting # => false
|
19
19
|
# Base.setting # => true
|
20
20
|
#
|
21
|
+
# In the above case as long as Subclass does not assign a value to setting
|
22
|
+
# by performing <tt>Subclass.setting = _something_ </tt>, <tt>Subclass.setting</tt>
|
23
|
+
# would read value assigned to parent class. Once Subclass assigns a value then
|
24
|
+
# the value assigned by Subclass would be returned.
|
25
|
+
#
|
21
26
|
# This matches normal Ruby method inheritance: think of writing an attribute
|
22
|
-
# on a subclass as overriding the reader method.
|
27
|
+
# on a subclass as overriding the reader method. However, you need to be aware
|
28
|
+
# when using +class_attribute+ with mutable structures as +Array+ or +Hash+.
|
29
|
+
# In such cases, you don't want to do changes in places but use setters:
|
30
|
+
#
|
31
|
+
# Base.setting = []
|
32
|
+
# Base.setting # => []
|
33
|
+
# Subclass.setting # => []
|
34
|
+
#
|
35
|
+
# # Appending in child changes both parent and child because it is the same object:
|
36
|
+
# Subclass.setting << :foo
|
37
|
+
# Base.setting # => [:foo]
|
38
|
+
# Subclass.setting # => [:foo]
|
39
|
+
#
|
40
|
+
# # Use setters to not propagate changes:
|
41
|
+
# Base.setting = []
|
42
|
+
# Subclass.setting += [:foo]
|
43
|
+
# Base.setting # => []
|
44
|
+
# Subclass.setting # => [:foo]
|
23
45
|
#
|
24
46
|
# For convenience, a query method is defined as well:
|
25
47
|
#
|
26
|
-
# Subclass.setting?
|
48
|
+
# Subclass.setting? # => false
|
27
49
|
#
|
28
50
|
# Instances may overwrite the class value in the same way:
|
29
51
|
#
|
@@ -50,6 +72,7 @@ class Class
|
|
50
72
|
remove_possible_method(:#{name})
|
51
73
|
define_method(:#{name}) { val }
|
52
74
|
end
|
75
|
+
val
|
53
76
|
end
|
54
77
|
|
55
78
|
def #{name}
|
@@ -3,11 +3,27 @@ require 'active_support/core_ext/array/extract_options'
|
|
3
3
|
# Extends the class object with class and instance accessors for class attributes,
|
4
4
|
# just like the native attr* accessors for instance attributes.
|
5
5
|
#
|
6
|
+
# Note that unlike +class_attribute+, if a subclass changes the value then that would
|
7
|
+
# also change the value for parent class. Similarly if parent class changes the value
|
8
|
+
# then that would change the value of subclasses too.
|
9
|
+
#
|
6
10
|
# class Person
|
7
11
|
# cattr_accessor :hair_colors
|
8
12
|
# end
|
9
13
|
#
|
10
14
|
# Person.hair_colors = [:brown, :black, :blonde, :red]
|
15
|
+
# Person.hair_colors # => [:brown, :black, :blonde, :red]
|
16
|
+
# Person.new.hair_colors # => [:brown, :black, :blonde, :red]
|
17
|
+
#
|
18
|
+
# To opt out of the instance writer method, pass :instance_writer => false.
|
19
|
+
# To opt out of the instance reader method, pass :instance_reader => false.
|
20
|
+
#
|
21
|
+
# class Person
|
22
|
+
# cattr_accessor :hair_colors, :instance_writer => false, :instance_reader => false
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# Person.new.hair_colors = [:brown] # => NoMethodError
|
26
|
+
# Person.new.hair_colors # => NoMethodError
|
11
27
|
class Class
|
12
28
|
def cattr_reader(*syms)
|
13
29
|
options = syms.extract_options!
|
@@ -1,17 +1,39 @@
|
|
1
1
|
require 'active_support/core_ext/object/duplicable'
|
2
2
|
require 'active_support/core_ext/array/extract_options'
|
3
3
|
|
4
|
-
#
|
4
|
+
# Retained for backward compatibility. Methods are now included in Class.
|
5
5
|
module ClassInheritableAttributes # :nodoc:
|
6
6
|
end
|
7
7
|
|
8
|
-
#
|
8
|
+
# It is recommended to use <tt>class_attribute</tt> over methods defined in this file. Please
|
9
|
+
# refer to documentation for <tt>class_attribute</tt> for more information. Officially it is not
|
10
|
+
# deprecated but <tt>class_attribute</tt> is faster.
|
11
|
+
#
|
12
|
+
# Allows attributes to be shared within an inheritance hierarchy. Each descendant gets a copy of
|
9
13
|
# their parents' attributes, instead of just a pointer to the same. This means that the child can add elements
|
10
14
|
# to, for example, an array without those additions being shared with either their parent, siblings, or
|
11
|
-
# children
|
15
|
+
# children. This is unlike the regular class-level attributes that are shared across the entire hierarchy.
|
12
16
|
#
|
13
17
|
# The copies of inheritable parent attributes are added to subclasses when they are created, via the
|
14
18
|
# +inherited+ hook.
|
19
|
+
#
|
20
|
+
# class Person
|
21
|
+
# class_inheritable_accessor :hair_colors
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# Person.hair_colors = [:brown, :black, :blonde, :red]
|
25
|
+
# Person.hair_colors # => [:brown, :black, :blonde, :red]
|
26
|
+
# Person.new.hair_colors # => [:brown, :black, :blonde, :red]
|
27
|
+
#
|
28
|
+
# To opt out of the instance writer method, pass :instance_writer => false.
|
29
|
+
# To opt out of the instance reader method, pass :instance_reader => false.
|
30
|
+
#
|
31
|
+
# class Person
|
32
|
+
# class_inheritable_accessor :hair_colors :instance_writer => false, :instance_reader => false
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# Person.new.hair_colors = [:brown] # => NoMethodError
|
36
|
+
# Person.new.hair_colors # => NoMethodError
|
15
37
|
class Class # :nodoc:
|
16
38
|
def class_inheritable_reader(*syms)
|
17
39
|
options = syms.extract_options!
|
@@ -7,7 +7,7 @@ require 'active_support/core_ext/time/zones'
|
|
7
7
|
class Date
|
8
8
|
if RUBY_VERSION < '1.9'
|
9
9
|
undef :>>
|
10
|
-
|
10
|
+
|
11
11
|
# Backported from 1.9. The one in 1.8 leads to incorrect next_month and
|
12
12
|
# friends for dates where the calendar reform is involved. It additionally
|
13
13
|
# prevents an infinite loop fixed in r27013.
|
@@ -40,23 +40,23 @@ class Date
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
#
|
43
|
+
# Returns true if the Date object's date lies in the past. Otherwise returns false.
|
44
44
|
def past?
|
45
45
|
self < ::Date.current
|
46
46
|
end
|
47
47
|
|
48
|
-
#
|
48
|
+
# Returns true if the Date object's date is today.
|
49
49
|
def today?
|
50
50
|
self.to_date == ::Date.current # we need the to_date because of DateTime
|
51
51
|
end
|
52
52
|
|
53
|
-
#
|
53
|
+
# Returns true if the Date object's date lies in the future.
|
54
54
|
def future?
|
55
55
|
self > ::Date.current
|
56
56
|
end
|
57
57
|
|
58
58
|
# Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
|
59
|
-
# and then subtracts the specified number of seconds
|
59
|
+
# and then subtracts the specified number of seconds.
|
60
60
|
def ago(seconds)
|
61
61
|
to_time_in_current_zone.since(-seconds)
|
62
62
|
end
|
@@ -127,22 +127,22 @@ class Date
|
|
127
127
|
)
|
128
128
|
end
|
129
129
|
|
130
|
-
# Returns a new Date/DateTime representing the time a number of specified months ago
|
130
|
+
# Returns a new Date/DateTime representing the time a number of specified months ago.
|
131
131
|
def months_ago(months)
|
132
132
|
advance(:months => -months)
|
133
133
|
end
|
134
134
|
|
135
|
-
# Returns a new Date/DateTime representing the time a number of specified months in the future
|
135
|
+
# Returns a new Date/DateTime representing the time a number of specified months in the future.
|
136
136
|
def months_since(months)
|
137
137
|
advance(:months => months)
|
138
138
|
end
|
139
139
|
|
140
|
-
# Returns a new Date/DateTime representing the time a number of specified years ago
|
140
|
+
# Returns a new Date/DateTime representing the time a number of specified years ago.
|
141
141
|
def years_ago(years)
|
142
142
|
advance(:years => -years)
|
143
143
|
end
|
144
144
|
|
145
|
-
# Returns a new Date/DateTime representing the time a number of specified years in the future
|
145
|
+
# Returns a new Date/DateTime representing the time a number of specified years in the future.
|
146
146
|
def years_since(years)
|
147
147
|
advance(:years => years)
|
148
148
|
end
|
@@ -152,22 +152,22 @@ class Date
|
|
152
152
|
years_ago(1)
|
153
153
|
end unless method_defined?(:prev_year)
|
154
154
|
|
155
|
-
#
|
155
|
+
# Shorthand for years_since(1)
|
156
156
|
def next_year
|
157
157
|
years_since(1)
|
158
158
|
end unless method_defined?(:next_year)
|
159
|
-
|
160
|
-
#
|
159
|
+
|
160
|
+
# Shorthand for months_ago(1)
|
161
161
|
def prev_month
|
162
162
|
months_ago(1)
|
163
163
|
end unless method_defined?(:prev_month)
|
164
164
|
|
165
|
-
#
|
165
|
+
# Shorthand for months_since(1)
|
166
166
|
def next_month
|
167
167
|
months_since(1)
|
168
168
|
end unless method_defined?(:next_month)
|
169
169
|
|
170
|
-
# Returns a new Date/DateTime representing the "start" of this week (i.e, Monday; DateTime objects will have time set to 0:00)
|
170
|
+
# Returns a new Date/DateTime representing the "start" of this week (i.e, Monday; DateTime objects will have time set to 0:00).
|
171
171
|
def beginning_of_week
|
172
172
|
days_to_monday = self.wday!=0 ? self.wday-1 : 6
|
173
173
|
result = self - days_to_monday
|
@@ -176,7 +176,7 @@ class Date
|
|
176
176
|
alias :monday :beginning_of_week
|
177
177
|
alias :at_beginning_of_week :beginning_of_week
|
178
178
|
|
179
|
-
# Returns a new Date/DateTime representing the end of this week (Sunday, DateTime objects will have time set to 23:59:59)
|
179
|
+
# Returns a new Date/DateTime representing the end of this week (Sunday, DateTime objects will have time set to 23:59:59).
|
180
180
|
def end_of_week
|
181
181
|
days_to_sunday = self.wday!=0 ? 7-self.wday : 0
|
182
182
|
result = self + days_to_sunday.days
|