activesupport 3.2.22.5 → 4.0.0.beta1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +325 -136
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -2
- data/lib/active_support.rb +8 -21
- data/lib/active_support/backtrace_cleaner.rb +33 -25
- data/lib/active_support/basic_object.rb +7 -17
- data/lib/active_support/benchmarkable.rb +19 -15
- data/lib/active_support/buffered_logger.rb +9 -113
- data/lib/active_support/cache.rb +203 -171
- data/lib/active_support/cache/file_store.rb +12 -12
- data/lib/active_support/cache/mem_cache_store.rb +24 -30
- data/lib/active_support/cache/memory_store.rb +2 -0
- data/lib/active_support/callbacks.rb +195 -247
- data/lib/active_support/concern.rb +16 -23
- data/lib/active_support/concurrency/latch.rb +27 -0
- data/lib/active_support/configurable.rb +69 -12
- data/lib/active_support/core_ext.rb +1 -0
- data/lib/active_support/core_ext/array.rb +0 -1
- data/lib/active_support/core_ext/array/access.rb +17 -9
- data/lib/active_support/core_ext/array/conversions.rb +113 -55
- data/lib/active_support/core_ext/array/extract_options.rb +2 -2
- data/lib/active_support/core_ext/array/grouping.rb +21 -22
- data/lib/active_support/core_ext/array/uniq_by.rb +12 -9
- data/lib/active_support/core_ext/array/wrap.rb +11 -14
- data/lib/active_support/core_ext/big_decimal/conversions.rb +7 -24
- data/lib/active_support/core_ext/class/attribute.rb +12 -8
- data/lib/active_support/core_ext/class/attribute_accessors.rb +14 -12
- data/lib/active_support/core_ext/class/delegating_attributes.rb +15 -19
- data/lib/active_support/core_ext/class/subclasses.rb +11 -5
- data/lib/active_support/core_ext/date.rb +6 -0
- data/lib/active_support/core_ext/date/calculations.rb +34 -188
- data/lib/active_support/core_ext/date/conversions.rb +16 -38
- data/lib/active_support/core_ext/date/infinite_comparable.rb +5 -0
- data/lib/active_support/core_ext/date/zones.rb +25 -2
- data/lib/active_support/core_ext/date_and_time/calculations.rb +232 -0
- data/lib/active_support/core_ext/date_time.rb +5 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +0 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +73 -65
- data/lib/active_support/core_ext/date_time/conversions.rb +21 -33
- data/lib/active_support/core_ext/date_time/infinite_comparable.rb +5 -0
- data/lib/active_support/core_ext/date_time/zones.rb +11 -8
- data/lib/active_support/core_ext/enumerable.rb +26 -73
- data/lib/active_support/core_ext/file.rb +0 -1
- data/lib/active_support/core_ext/file/atomic.rb +27 -11
- data/lib/active_support/core_ext/hash.rb +0 -1
- data/lib/active_support/core_ext/hash/conversions.rb +145 -79
- data/lib/active_support/core_ext/hash/deep_merge.rb +14 -8
- data/lib/active_support/core_ext/hash/diff.rb +5 -4
- data/lib/active_support/core_ext/hash/except.rb +1 -9
- data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -5
- data/lib/active_support/core_ext/hash/keys.rb +108 -24
- data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -3
- data/lib/active_support/core_ext/hash/slice.rb +12 -12
- data/lib/active_support/core_ext/infinite_comparable.rb +35 -0
- data/lib/active_support/core_ext/integer/inflections.rb +13 -1
- data/lib/active_support/core_ext/integer/time.rb +17 -12
- data/lib/active_support/core_ext/kernel/debugger.rb +2 -2
- data/lib/active_support/core_ext/kernel/reporting.rb +36 -22
- data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -7
- data/lib/active_support/core_ext/load_error.rb +7 -5
- data/lib/active_support/core_ext/logger.rb +7 -23
- data/lib/active_support/core_ext/marshal.rb +19 -0
- data/lib/active_support/core_ext/module.rb +1 -3
- data/lib/active_support/core_ext/module/aliasing.rb +8 -9
- data/lib/active_support/core_ext/module/anonymous.rb +2 -7
- data/lib/active_support/core_ext/module/attr_internal.rb +0 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +12 -10
- data/lib/active_support/core_ext/module/delegation.rb +57 -40
- data/lib/active_support/core_ext/module/deprecation.rb +19 -3
- data/lib/active_support/core_ext/module/introspection.rb +17 -27
- data/lib/active_support/core_ext/module/qualified_const.rb +8 -20
- data/lib/active_support/core_ext/module/remove_method.rb +1 -5
- data/lib/active_support/core_ext/numeric.rb +2 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +135 -0
- data/lib/active_support/core_ext/numeric/infinite_comparable.rb +9 -0
- data/lib/active_support/core_ext/numeric/time.rb +6 -6
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/object/acts_like.rb +4 -4
- data/lib/active_support/core_ext/object/blank.rb +7 -23
- data/lib/active_support/core_ext/object/deep_dup.rb +46 -0
- data/lib/active_support/core_ext/object/duplicable.rb +1 -30
- data/lib/active_support/core_ext/object/inclusion.rb +6 -6
- data/lib/active_support/core_ext/object/instance_variables.rb +7 -12
- data/lib/active_support/core_ext/object/to_json.rb +8 -0
- data/lib/active_support/core_ext/object/to_param.rb +5 -2
- data/lib/active_support/core_ext/object/try.rb +46 -25
- data/lib/active_support/core_ext/object/with_options.rb +7 -8
- data/lib/active_support/core_ext/proc.rb +3 -0
- data/lib/active_support/core_ext/range.rb +0 -2
- data/lib/active_support/core_ext/range/conversions.rb +0 -2
- data/lib/active_support/core_ext/range/include_range.rb +1 -1
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/string.rb +2 -2
- data/lib/active_support/core_ext/string/access.rb +95 -90
- data/lib/active_support/core_ext/string/conversions.rb +29 -38
- data/lib/active_support/core_ext/string/encoding.rb +6 -9
- data/lib/active_support/core_ext/string/filters.rb +24 -18
- data/lib/active_support/core_ext/string/indent.rb +43 -0
- data/lib/active_support/core_ext/string/inflections.rb +70 -60
- data/lib/active_support/core_ext/string/inquiry.rb +2 -2
- data/lib/active_support/core_ext/string/multibyte.rb +41 -64
- data/lib/active_support/core_ext/string/output_safety.rb +59 -51
- data/lib/active_support/core_ext/string/zones.rb +13 -0
- data/lib/active_support/core_ext/struct.rb +6 -0
- data/lib/active_support/core_ext/thread.rb +74 -0
- data/lib/active_support/core_ext/time.rb +6 -0
- data/lib/active_support/core_ext/time/calculations.rb +105 -193
- data/lib/active_support/core_ext/time/conversions.rb +27 -51
- data/lib/active_support/core_ext/time/infinite_comparable.rb +5 -0
- data/lib/active_support/core_ext/time/marshal.rb +0 -27
- data/lib/active_support/core_ext/time/zones.rb +27 -17
- data/lib/active_support/core_ext/uri.rb +13 -17
- data/lib/active_support/dependencies.rb +160 -141
- data/lib/active_support/dependencies/autoload.rb +47 -20
- data/lib/active_support/deprecation.rb +39 -14
- data/lib/active_support/deprecation/behaviors.rb +44 -30
- data/lib/active_support/deprecation/instance_delegator.rb +24 -0
- data/lib/active_support/deprecation/method_wrappers.rb +33 -18
- data/lib/active_support/deprecation/proxy_wrappers.rb +58 -13
- data/lib/active_support/deprecation/reporting.rb +40 -11
- data/lib/active_support/descendants_tracker.rb +34 -19
- data/lib/active_support/duration.rb +6 -8
- data/lib/active_support/file_update_checker.rb +63 -47
- data/lib/active_support/gzip.rb +11 -5
- data/lib/active_support/hash_with_indifferent_access.rb +112 -37
- data/lib/active_support/i18n.rb +4 -0
- data/lib/active_support/i18n_railtie.rb +5 -22
- data/lib/active_support/inflections.rb +14 -12
- data/lib/active_support/inflector/inflections.rb +108 -71
- data/lib/active_support/inflector/methods.rb +181 -160
- data/lib/active_support/inflector/transliterate.rb +16 -17
- data/lib/active_support/json/decoding.rb +18 -17
- data/lib/active_support/json/encoding.rb +93 -39
- data/lib/active_support/json/variable.rb +10 -1
- data/lib/active_support/key_generator.rb +75 -0
- data/lib/active_support/lazy_load_hooks.rb +21 -19
- data/lib/active_support/locale/en.yml +100 -3
- data/lib/active_support/log_subscriber.rb +56 -36
- data/lib/active_support/log_subscriber/test_helper.rb +18 -15
- data/lib/active_support/logger.rb +57 -0
- data/lib/active_support/logger_silence.rb +24 -0
- data/lib/active_support/message_encryptor.rb +32 -29
- data/lib/active_support/message_verifier.rb +8 -14
- data/lib/active_support/multibyte.rb +5 -28
- data/lib/active_support/multibyte/chars.rb +80 -333
- data/lib/active_support/multibyte/unicode.rb +74 -64
- data/lib/active_support/notifications.rb +57 -25
- data/lib/active_support/notifications/fanout.rb +105 -18
- data/lib/active_support/notifications/instrumenter.rb +32 -13
- data/lib/active_support/number_helper.rb +636 -0
- data/lib/active_support/ordered_hash.rb +8 -190
- data/lib/active_support/ordered_options.rb +21 -23
- data/lib/active_support/proxy_object.rb +13 -0
- data/lib/active_support/rails.rb +27 -0
- data/lib/active_support/railtie.rb +12 -32
- data/lib/active_support/rescuable.rb +9 -4
- data/lib/active_support/string_inquirer.rb +13 -8
- data/lib/active_support/tagged_logging.rb +51 -73
- data/lib/active_support/test_case.rb +46 -17
- data/lib/active_support/testing/assertions.rb +56 -26
- data/lib/active_support/testing/autorun.rb +5 -0
- data/lib/active_support/testing/constant_lookup.rb +52 -0
- data/lib/active_support/testing/declarative.rb +1 -1
- data/lib/active_support/testing/deprecation.rb +0 -19
- data/lib/active_support/testing/isolation.rb +25 -58
- data/lib/active_support/testing/pending.rb +5 -43
- data/lib/active_support/testing/setup_and_teardown.rb +6 -92
- data/lib/active_support/testing/tagged_logging.rb +25 -0
- data/lib/active_support/time.rb +6 -21
- data/lib/active_support/time_with_zone.rb +78 -43
- data/lib/active_support/values/time_zone.rb +77 -58
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +4 -4
- data/lib/active_support/xml_mini.rb +35 -17
- data/lib/active_support/xml_mini/jdom.rb +9 -17
- data/lib/active_support/xml_mini/libxml.rb +1 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +1 -2
- data/lib/active_support/xml_mini/nokogiri.rb +1 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -2
- data/lib/active_support/xml_mini/rexml.rb +6 -8
- metadata +107 -77
- data/lib/active_support/base64.rb +0 -54
- data/lib/active_support/core_ext/array/random_access.rb +0 -30
- data/lib/active_support/core_ext/date/freeze.rb +0 -33
- data/lib/active_support/core_ext/exception.rb +0 -3
- data/lib/active_support/core_ext/file/path.rb +0 -5
- data/lib/active_support/core_ext/float.rb +0 -1
- data/lib/active_support/core_ext/float/rounding.rb +0 -19
- data/lib/active_support/core_ext/hash/deep_dup.rb +0 -18
- data/lib/active_support/core_ext/io.rb +0 -15
- data/lib/active_support/core_ext/module/method_names.rb +0 -14
- data/lib/active_support/core_ext/module/synchronization.rb +0 -45
- data/lib/active_support/core_ext/process.rb +0 -1
- data/lib/active_support/core_ext/process/daemon.rb +0 -23
- data/lib/active_support/core_ext/range/blockless_step.rb +0 -29
- data/lib/active_support/core_ext/range/cover.rb +0 -3
- data/lib/active_support/core_ext/rexml.rb +0 -46
- data/lib/active_support/core_ext/string/interpolation.rb +0 -2
- data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +0 -10
- data/lib/active_support/memoizable.rb +0 -116
- data/lib/active_support/multibyte/exceptions.rb +0 -8
- data/lib/active_support/multibyte/utils.rb +0 -60
- data/lib/active_support/ruby/shim.rb +0 -22
- data/lib/active_support/security_utils.rb +0 -27
- data/lib/active_support/testing/mochaing.rb +0 -7
- data/lib/active_support/testing/performance.rb +0 -317
- data/lib/active_support/testing/performance/jruby.rb +0 -115
- data/lib/active_support/testing/performance/rubinius.rb +0 -113
- data/lib/active_support/testing/performance/ruby.rb +0 -152
- data/lib/active_support/testing/performance/ruby/mri.rb +0 -57
- data/lib/active_support/testing/performance/ruby/yarv.rb +0 -57
- data/lib/active_support/time/autoload.rb +0 -5
- data/lib/active_support/whiny_nil.rb +0 -24
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'active_support/deprecation'
|
2
|
-
|
3
1
|
module ActiveSupport
|
4
2
|
# A typical module looks like this:
|
5
3
|
#
|
@@ -7,7 +5,7 @@ module ActiveSupport
|
|
7
5
|
# def self.included(base)
|
8
6
|
# base.extend ClassMethods
|
9
7
|
# base.class_eval do
|
10
|
-
# scope :disabled, where(:
|
8
|
+
# scope :disabled, -> { where(disabled: true) }
|
11
9
|
# end
|
12
10
|
# end
|
13
11
|
#
|
@@ -16,7 +14,8 @@ module ActiveSupport
|
|
16
14
|
# end
|
17
15
|
# end
|
18
16
|
#
|
19
|
-
# By using <tt>ActiveSupport::Concern</tt> the above module could instead be
|
17
|
+
# By using <tt>ActiveSupport::Concern</tt> the above module could instead be
|
18
|
+
# written as:
|
20
19
|
#
|
21
20
|
# require 'active_support/concern'
|
22
21
|
#
|
@@ -24,7 +23,7 @@ module ActiveSupport
|
|
24
23
|
# extend ActiveSupport::Concern
|
25
24
|
#
|
26
25
|
# included do
|
27
|
-
# scope :disabled, where(:
|
26
|
+
# scope :disabled, -> { where(disabled: true) }
|
28
27
|
# end
|
29
28
|
#
|
30
29
|
# module ClassMethods
|
@@ -32,8 +31,9 @@ module ActiveSupport
|
|
32
31
|
# end
|
33
32
|
# end
|
34
33
|
#
|
35
|
-
# Moreover, it gracefully handles module dependencies. Given a +Foo+ module
|
36
|
-
# module which depends on the former, we would typically write the
|
34
|
+
# Moreover, it gracefully handles module dependencies. Given a +Foo+ module
|
35
|
+
# and a +Bar+ module which depends on the former, we would typically write the
|
36
|
+
# following:
|
37
37
|
#
|
38
38
|
# module Foo
|
39
39
|
# def self.included(base)
|
@@ -56,11 +56,11 @@ module ActiveSupport
|
|
56
56
|
# include Bar # Bar is the module that Host really needs
|
57
57
|
# end
|
58
58
|
#
|
59
|
-
# But why should +Host+ care about +Bar+'s dependencies, namely +Foo+? We
|
60
|
-
# these from +Host+ directly including +Foo+ in +Bar+:
|
59
|
+
# But why should +Host+ care about +Bar+'s dependencies, namely +Foo+? We
|
60
|
+
# could try to hide these from +Host+ directly including +Foo+ in +Bar+:
|
61
61
|
#
|
62
62
|
# module Bar
|
63
|
-
# include Foo
|
63
|
+
# include Foo
|
64
64
|
# def self.included(base)
|
65
65
|
# base.method_injected_by_foo
|
66
66
|
# end
|
@@ -70,18 +70,17 @@ module ActiveSupport
|
|
70
70
|
# include Bar
|
71
71
|
# end
|
72
72
|
#
|
73
|
-
# Unfortunately this won't work, since when +Foo+ is included, its <tt>base</tt>
|
74
|
-
# not the +Host+ class. With <tt>ActiveSupport::Concern</tt>,
|
73
|
+
# Unfortunately this won't work, since when +Foo+ is included, its <tt>base</tt>
|
74
|
+
# is the +Bar+ module, not the +Host+ class. With <tt>ActiveSupport::Concern</tt>,
|
75
|
+
# module dependencies are properly resolved:
|
75
76
|
#
|
76
77
|
# require 'active_support/concern'
|
77
78
|
#
|
78
79
|
# module Foo
|
79
80
|
# extend ActiveSupport::Concern
|
80
81
|
# included do
|
81
|
-
#
|
82
|
-
#
|
83
|
-
# ...
|
84
|
-
# end
|
82
|
+
# def self.method_injected_by_foo
|
83
|
+
# ...
|
85
84
|
# end
|
86
85
|
# end
|
87
86
|
# end
|
@@ -98,9 +97,8 @@ module ActiveSupport
|
|
98
97
|
# class Host
|
99
98
|
# include Bar # works, Bar takes care now of its dependencies
|
100
99
|
# end
|
101
|
-
#
|
102
100
|
module Concern
|
103
|
-
def self.extended(base)
|
101
|
+
def self.extended(base) #:nodoc:
|
104
102
|
base.instance_variable_set("@_dependencies", [])
|
105
103
|
end
|
106
104
|
|
@@ -113,11 +111,6 @@ module ActiveSupport
|
|
113
111
|
@_dependencies.each { |dep| base.send(:include, dep) }
|
114
112
|
super
|
115
113
|
base.extend const_get("ClassMethods") if const_defined?("ClassMethods")
|
116
|
-
if const_defined?("InstanceMethods")
|
117
|
-
base.send :include, const_get("InstanceMethods")
|
118
|
-
ActiveSupport::Deprecation.warn "The InstanceMethods module inside ActiveSupport::Concern will be " \
|
119
|
-
"no longer included automatically. Please define instance methods directly in #{self} instead.", caller
|
120
|
-
end
|
121
114
|
base.class_eval(&@_included_block) if instance_variable_defined?("@_included_block")
|
122
115
|
end
|
123
116
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'thread'
|
2
|
+
require 'monitor'
|
3
|
+
|
4
|
+
module ActiveSupport
|
5
|
+
module Concurrency
|
6
|
+
class Latch
|
7
|
+
def initialize(count = 1)
|
8
|
+
@count = count
|
9
|
+
@lock = Monitor.new
|
10
|
+
@cv = @lock.new_cond
|
11
|
+
end
|
12
|
+
|
13
|
+
def release
|
14
|
+
@lock.synchronize do
|
15
|
+
@count -= 1 if @count > 0
|
16
|
+
@cv.broadcast if @count.zero?
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def await
|
21
|
+
@lock.synchronize do
|
22
|
+
@cv.wait_while { @count > 0 }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
require 'active_support/concern'
|
2
2
|
require 'active_support/ordered_options'
|
3
|
-
require 'active_support/core_ext/kernel/singleton_class'
|
4
|
-
require 'active_support/core_ext/module/delegation'
|
5
3
|
require 'active_support/core_ext/array/extract_options'
|
6
4
|
|
7
5
|
module ActiveSupport
|
@@ -15,7 +13,7 @@ module ActiveSupport
|
|
15
13
|
self.class.compile_methods!(keys)
|
16
14
|
end
|
17
15
|
|
18
|
-
#
|
16
|
+
# Compiles reader methods so we don't have to go through method_missing.
|
19
17
|
def self.compile_methods!(keys)
|
20
18
|
keys.reject { |m| method_defined?(m) }.each do |key|
|
21
19
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
@@ -39,29 +37,89 @@ module ActiveSupport
|
|
39
37
|
yield config
|
40
38
|
end
|
41
39
|
|
42
|
-
# Allows you to add shortcut so that you don't have to refer to attribute
|
43
|
-
# Also look at the example for config to contrast.
|
40
|
+
# Allows you to add shortcut so that you don't have to refer to attribute
|
41
|
+
# through config. Also look at the example for config to contrast.
|
42
|
+
#
|
43
|
+
# Defines both class and instance config accessors.
|
44
44
|
#
|
45
45
|
# class User
|
46
46
|
# include ActiveSupport::Configurable
|
47
47
|
# config_accessor :allowed_access
|
48
48
|
# end
|
49
49
|
#
|
50
|
+
# User.allowed_access # => nil
|
51
|
+
# User.allowed_access = false
|
52
|
+
# User.allowed_access # => false
|
53
|
+
#
|
50
54
|
# user = User.new
|
55
|
+
# user.allowed_access # => false
|
51
56
|
# user.allowed_access = true
|
52
57
|
# user.allowed_access # => true
|
53
58
|
#
|
59
|
+
# User.allowed_access # => false
|
60
|
+
#
|
61
|
+
# The attribute name must be a valid method name in Ruby.
|
62
|
+
#
|
63
|
+
# class User
|
64
|
+
# include ActiveSupport::Configurable
|
65
|
+
# config_accessor :"1_Badname"
|
66
|
+
# end
|
67
|
+
# # => NameError: invalid config attribute name
|
68
|
+
#
|
69
|
+
# To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
|
70
|
+
# To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
|
71
|
+
#
|
72
|
+
# class User
|
73
|
+
# include ActiveSupport::Configurable
|
74
|
+
# config_accessor :allowed_access, instance_reader: false, instance_writer: false
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# User.allowed_access = false
|
78
|
+
# User.allowed_access # => false
|
79
|
+
#
|
80
|
+
# User.new.allowed_access = true # => NoMethodError
|
81
|
+
# User.new.allowed_access # => NoMethodError
|
82
|
+
#
|
83
|
+
# Or pass <tt>instance_accessor: false</tt>, to opt out both instance methods.
|
84
|
+
#
|
85
|
+
# class User
|
86
|
+
# include ActiveSupport::Configurable
|
87
|
+
# config_accessor :allowed_access, instance_accessor: false
|
88
|
+
# end
|
89
|
+
#
|
90
|
+
# User.allowed_access = false
|
91
|
+
# User.allowed_access # => false
|
92
|
+
#
|
93
|
+
# User.new.allowed_access = true # => NoMethodError
|
94
|
+
# User.new.allowed_access # => NoMethodError
|
95
|
+
#
|
96
|
+
# Also you can pass a block to set up the attribute with a default value.
|
97
|
+
#
|
98
|
+
# class User
|
99
|
+
# include ActiveSupport::Configurable
|
100
|
+
# config_accessor :hair_colors do
|
101
|
+
# [:brown, :black, :blonde, :red]
|
102
|
+
# end
|
103
|
+
# end
|
104
|
+
#
|
105
|
+
# User.hair_colors # => [:brown, :black, :blonde, :red]
|
54
106
|
def config_accessor(*names)
|
55
107
|
options = names.extract_options!
|
56
108
|
|
57
109
|
names.each do |name|
|
58
|
-
|
59
|
-
writer, line = "def #{name}=(value); config.#{name} = value; end", __LINE__
|
110
|
+
raise NameError.new('invalid config attribute name') unless name =~ /^[_A-Za-z]\w*$/
|
60
111
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
class_eval
|
112
|
+
reader, reader_line = "def #{name}; config.#{name}; end", __LINE__
|
113
|
+
writer, writer_line = "def #{name}=(value); config.#{name} = value; end", __LINE__
|
114
|
+
|
115
|
+
singleton_class.class_eval reader, __FILE__, reader_line
|
116
|
+
singleton_class.class_eval writer, __FILE__, writer_line
|
117
|
+
|
118
|
+
unless options[:instance_accessor] == false
|
119
|
+
class_eval reader, __FILE__, reader_line unless options[:instance_reader] == false
|
120
|
+
class_eval writer, __FILE__, writer_line unless options[:instance_writer] == false
|
121
|
+
end
|
122
|
+
send("#{name}=", yield) if block_given?
|
65
123
|
end
|
66
124
|
end
|
67
125
|
end
|
@@ -81,7 +139,6 @@ module ActiveSupport
|
|
81
139
|
#
|
82
140
|
# user.config.allowed_access # => true
|
83
141
|
# user.config.level # => 1
|
84
|
-
#
|
85
142
|
def config
|
86
143
|
@_config ||= self.class.config.inheritable_copy
|
87
144
|
end
|
@@ -4,5 +4,4 @@ require 'active_support/core_ext/array/uniq_by'
|
|
4
4
|
require 'active_support/core_ext/array/conversions'
|
5
5
|
require 'active_support/core_ext/array/extract_options'
|
6
6
|
require 'active_support/core_ext/array/grouping'
|
7
|
-
require 'active_support/core_ext/array/random_access'
|
8
7
|
require 'active_support/core_ext/array/prepend_and_append'
|
@@ -1,40 +1,48 @@
|
|
1
1
|
class Array
|
2
2
|
# Returns the tail of the array from +position+.
|
3
3
|
#
|
4
|
-
# %w( a b c d ).from(0) # =>
|
5
|
-
# %w( a b c d ).from(2) # =>
|
6
|
-
# %w( a b c d ).from(10) # =>
|
7
|
-
# %w().from(0) # =>
|
4
|
+
# %w( a b c d ).from(0) # => ["a", "b", "c", "d"]
|
5
|
+
# %w( a b c d ).from(2) # => ["c", "d"]
|
6
|
+
# %w( a b c d ).from(10) # => []
|
7
|
+
# %w().from(0) # => []
|
8
8
|
def from(position)
|
9
9
|
self[position, length] || []
|
10
10
|
end
|
11
11
|
|
12
12
|
# Returns the beginning of the array up to +position+.
|
13
13
|
#
|
14
|
-
# %w( a b c d ).to(0) # =>
|
15
|
-
# %w( a b c d ).to(2) # =>
|
16
|
-
# %w( a b c d ).to(10) # =>
|
17
|
-
# %w().to(0) # =>
|
14
|
+
# %w( a b c d ).to(0) # => ["a"]
|
15
|
+
# %w( a b c d ).to(2) # => ["a", "b", "c"]
|
16
|
+
# %w( a b c d ).to(10) # => ["a", "b", "c", "d"]
|
17
|
+
# %w().to(0) # => []
|
18
18
|
def to(position)
|
19
|
-
|
19
|
+
first position + 1
|
20
20
|
end
|
21
21
|
|
22
22
|
# Equal to <tt>self[1]</tt>.
|
23
|
+
#
|
24
|
+
# %w( a b c d e ).second # => "b"
|
23
25
|
def second
|
24
26
|
self[1]
|
25
27
|
end
|
26
28
|
|
27
29
|
# Equal to <tt>self[2]</tt>.
|
30
|
+
#
|
31
|
+
# %w( a b c d e ).third # => "c"
|
28
32
|
def third
|
29
33
|
self[2]
|
30
34
|
end
|
31
35
|
|
32
36
|
# Equal to <tt>self[3]</tt>.
|
37
|
+
#
|
38
|
+
# %w( a b c d e ).fourth # => "d"
|
33
39
|
def fourth
|
34
40
|
self[3]
|
35
41
|
end
|
36
42
|
|
37
43
|
# Equal to <tt>self[4]</tt>.
|
44
|
+
#
|
45
|
+
# %w( a b c d e ).fifth # => "e"
|
38
46
|
def fifth
|
39
47
|
self[4]
|
40
48
|
end
|
@@ -1,41 +1,97 @@
|
|
1
1
|
require 'active_support/xml_mini'
|
2
2
|
require 'active_support/core_ext/hash/keys'
|
3
|
-
require 'active_support/core_ext/hash/reverse_merge'
|
4
3
|
require 'active_support/core_ext/string/inflections'
|
4
|
+
require 'active_support/core_ext/object/to_param'
|
5
|
+
require 'active_support/core_ext/object/to_query'
|
5
6
|
|
6
7
|
class Array
|
7
|
-
# Converts the array to a comma-separated sentence where the last element is
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
8
|
+
# Converts the array to a comma-separated sentence where the last element is
|
9
|
+
# joined by the connector word.
|
10
|
+
#
|
11
|
+
# You can pass the following options to change the default behavior. If you
|
12
|
+
# pass an option key that doesn't exist in the list below, it will raise an
|
13
|
+
# <tt>ArgumentError</tt>.
|
14
|
+
#
|
15
|
+
# Options:
|
16
|
+
#
|
17
|
+
# * <tt>:words_connector</tt> - The sign or word used to join the elements
|
18
|
+
# in arrays with two or more elements (default: ", ").
|
19
|
+
# * <tt>:two_words_connector</tt> - The sign or word used to join the elements
|
20
|
+
# in arrays with two elements (default: " and ").
|
21
|
+
# * <tt>:last_word_connector</tt> - The sign or word used to join the last element
|
22
|
+
# in arrays with three or more elements (default: ", and ").
|
23
|
+
# * <tt>:locale</tt> - If +i18n+ is available, you can set a locale and use
|
24
|
+
# the connector options defined on the 'support.array' namespace in the
|
25
|
+
# corresponding dictionary file.
|
26
|
+
#
|
27
|
+
# [].to_sentence # => ""
|
28
|
+
# ['one'].to_sentence # => "one"
|
29
|
+
# ['one', 'two'].to_sentence # => "one and two"
|
30
|
+
# ['one', 'two', 'three'].to_sentence # => "one, two, and three"
|
31
|
+
#
|
32
|
+
# ['one', 'two'].to_sentence(passing: 'invalid option')
|
33
|
+
# # => ArgumentError: Unknown key :passing
|
34
|
+
#
|
35
|
+
# ['one', 'two'].to_sentence(two_words_connector: '-')
|
36
|
+
# # => "one-two"
|
37
|
+
#
|
38
|
+
# ['one', 'two', 'three'].to_sentence(words_connector: ' or ', last_word_connector: ' or at least ')
|
39
|
+
# # => "one or two or at least three"
|
40
|
+
#
|
41
|
+
# Examples using <tt>:locale</tt> option:
|
42
|
+
#
|
43
|
+
# # Given this locale dictionary:
|
44
|
+
# #
|
45
|
+
# # es:
|
46
|
+
# # support:
|
47
|
+
# # array:
|
48
|
+
# # words_connector: " o "
|
49
|
+
# # two_words_connector: " y "
|
50
|
+
# # last_word_connector: " o al menos "
|
51
|
+
#
|
52
|
+
# ['uno', 'dos'].to_sentence(locale: :es)
|
53
|
+
# # => "uno y dos"
|
54
|
+
#
|
55
|
+
# ['uno', 'dos', 'tres'].to_sentence(locale: :es)
|
56
|
+
# # => "uno o dos o al menos tres"
|
11
57
|
def to_sentence(options = {})
|
58
|
+
options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)
|
59
|
+
|
60
|
+
default_connectors = {
|
61
|
+
:words_connector => ', ',
|
62
|
+
:two_words_connector => ' and ',
|
63
|
+
:last_word_connector => ', and '
|
64
|
+
}
|
12
65
|
if defined?(I18n)
|
13
|
-
|
14
|
-
|
15
|
-
default_last_word_connector = I18n.translate(:'support.array.last_word_connector', :locale => options[:locale])
|
16
|
-
else
|
17
|
-
default_words_connector = ", "
|
18
|
-
default_two_words_connector = " and "
|
19
|
-
default_last_word_connector = ", and "
|
66
|
+
i18n_connectors = I18n.translate(:'support.array', locale: options[:locale], default: {})
|
67
|
+
default_connectors.merge!(i18n_connectors)
|
20
68
|
end
|
21
|
-
|
22
|
-
options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)
|
23
|
-
options.reverse_merge! :words_connector => default_words_connector, :two_words_connector => default_two_words_connector, :last_word_connector => default_last_word_connector
|
69
|
+
options = default_connectors.merge!(options)
|
24
70
|
|
25
71
|
case length
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
72
|
+
when 0
|
73
|
+
''
|
74
|
+
when 1
|
75
|
+
self[0].to_s.dup
|
76
|
+
when 2
|
77
|
+
"#{self[0]}#{options[:two_words_connector]}#{self[1]}"
|
78
|
+
else
|
79
|
+
"#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
|
34
80
|
end
|
35
81
|
end
|
36
82
|
|
37
83
|
# Converts a collection of elements into a formatted string by calling
|
38
|
-
# <tt>to_s</tt> on all elements and joining them:
|
84
|
+
# <tt>to_s</tt> on all elements and joining them. Having this model:
|
85
|
+
#
|
86
|
+
# class Blog < ActiveRecord::Base
|
87
|
+
# def to_s
|
88
|
+
# title
|
89
|
+
# end
|
90
|
+
# end
|
91
|
+
#
|
92
|
+
# Blog.all.map(&:title) #=> ["First Post", "Second Post", "Third post"]
|
93
|
+
#
|
94
|
+
# <tt>to_formatted_s</tt> shows us:
|
39
95
|
#
|
40
96
|
# Blog.all.to_formatted_s # => "First PostSecond PostThird Post"
|
41
97
|
#
|
@@ -45,14 +101,14 @@ class Array
|
|
45
101
|
# Blog.all.to_formatted_s(:db) # => "1,2,3"
|
46
102
|
def to_formatted_s(format = :default)
|
47
103
|
case format
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
else
|
52
|
-
collect { |element| element.id }.join(",")
|
53
|
-
end
|
104
|
+
when :db
|
105
|
+
if empty?
|
106
|
+
'null'
|
54
107
|
else
|
55
|
-
|
108
|
+
collect { |element| element.id }.join(',')
|
109
|
+
end
|
110
|
+
else
|
111
|
+
to_default_s
|
56
112
|
end
|
57
113
|
end
|
58
114
|
alias_method :to_default_s, :to_s
|
@@ -86,20 +142,20 @@ class Array
|
|
86
142
|
# </project>
|
87
143
|
# </projects>
|
88
144
|
#
|
89
|
-
# Otherwise the root element is "
|
145
|
+
# Otherwise the root element is "objects":
|
90
146
|
#
|
91
|
-
# [{:
|
147
|
+
# [{ foo: 1, bar: 2}, { baz: 3}].to_xml
|
92
148
|
#
|
93
149
|
# <?xml version="1.0" encoding="UTF-8"?>
|
94
|
-
# <
|
95
|
-
# <
|
150
|
+
# <objects type="array">
|
151
|
+
# <object>
|
96
152
|
# <bar type="integer">2</bar>
|
97
153
|
# <foo type="integer">1</foo>
|
98
|
-
# </
|
99
|
-
# <
|
154
|
+
# </object>
|
155
|
+
# <object>
|
100
156
|
# <baz type="integer">3</baz>
|
101
|
-
# </
|
102
|
-
# </
|
157
|
+
# </object>
|
158
|
+
# </objects>
|
103
159
|
#
|
104
160
|
# If the collection is empty the root element is "nil-classes" by default:
|
105
161
|
#
|
@@ -110,7 +166,7 @@ class Array
|
|
110
166
|
#
|
111
167
|
# To ensure a meaningful root element use the <tt>:root</tt> option:
|
112
168
|
#
|
113
|
-
# customer_with_no_projects.projects.to_xml(:
|
169
|
+
# customer_with_no_projects.projects.to_xml(root: 'projects')
|
114
170
|
#
|
115
171
|
# <?xml version="1.0" encoding="UTF-8"?>
|
116
172
|
# <projects type="array"/>
|
@@ -120,7 +176,7 @@ class Array
|
|
120
176
|
#
|
121
177
|
# The +options+ hash is passed downwards:
|
122
178
|
#
|
123
|
-
# Message.all.to_xml(:
|
179
|
+
# Message.all.to_xml(skip_types: true)
|
124
180
|
#
|
125
181
|
# <?xml version="1.0" encoding="UTF-8"?>
|
126
182
|
# <messages>
|
@@ -138,27 +194,29 @@ class Array
|
|
138
194
|
|
139
195
|
options = options.dup
|
140
196
|
options[:indent] ||= 2
|
141
|
-
options[:builder] ||= Builder::XmlMarkup.new(:
|
142
|
-
options[:root] ||=
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
197
|
+
options[:builder] ||= Builder::XmlMarkup.new(indent: options[:indent])
|
198
|
+
options[:root] ||= \
|
199
|
+
if first.class != Hash && all? { |e| e.is_a?(first.class) }
|
200
|
+
underscored = ActiveSupport::Inflector.underscore(first.class.name)
|
201
|
+
ActiveSupport::Inflector.pluralize(underscored).tr('/', '_')
|
202
|
+
else
|
203
|
+
'objects'
|
204
|
+
end
|
148
205
|
|
149
206
|
builder = options[:builder]
|
150
207
|
builder.instruct! unless options.delete(:skip_instruct)
|
151
208
|
|
152
209
|
root = ActiveSupport::XmlMini.rename_key(options[:root].to_s, options)
|
153
210
|
children = options.delete(:children) || root.singularize
|
211
|
+
attributes = options[:skip_types] ? {} : { type: 'array' }
|
154
212
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
213
|
+
if empty?
|
214
|
+
builder.tag!(root, attributes)
|
215
|
+
else
|
216
|
+
builder.tag!(root, attributes) do
|
217
|
+
each { |value| ActiveSupport::XmlMini.to_tag(children, value, options) }
|
218
|
+
yield builder if block_given?
|
219
|
+
end
|
161
220
|
end
|
162
221
|
end
|
163
|
-
|
164
222
|
end
|