activesupport 3.2.22.5 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +364 -135
- data/MIT-LICENSE +1 -1
- data/README.rdoc +6 -4
- 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/file_store.rb +14 -14
- 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/cache/strategy/local_cache.rb +48 -37
- data/lib/active_support/cache.rb +228 -183
- data/lib/active_support/callbacks.rb +201 -253
- 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/array/access.rb +17 -9
- data/lib/active_support/core_ext/array/conversions.rb +115 -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 +13 -16
- data/lib/active_support/core_ext/array.rb +0 -1
- data/lib/active_support/core_ext/benchmark.rb +7 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -24
- data/lib/active_support/core_ext/class/attribute.rb +40 -32
- 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/calculations.rb +44 -187
- data/lib/active_support/core_ext/date/conversions.rb +16 -38
- data/lib/active_support/core_ext/date/zones.rb +25 -2
- data/lib/active_support/core_ext/date.rb +5 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +232 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +0 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +77 -62
- data/lib/active_support/core_ext/date_time/conversions.rb +21 -33
- data/lib/active_support/core_ext/date_time/zones.rb +11 -8
- data/lib/active_support/core_ext/date_time.rb +4 -0
- data/lib/active_support/core_ext/enumerable.rb +26 -73
- data/lib/active_support/core_ext/file/atomic.rb +27 -11
- data/lib/active_support/core_ext/file.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/hash.rb +0 -1
- 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 +21 -0
- 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 +92 -49
- 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/module.rb +1 -3
- data/lib/active_support/core_ext/numeric/conversions.rb +135 -0
- data/lib/active_support/core_ext/numeric/time.rb +6 -6
- data/lib/active_support/core_ext/numeric.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 +8 -7
- 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/object.rb +1 -0
- data/lib/active_support/core_ext/proc.rb +3 -0
- data/lib/active_support/core_ext/range/conversions.rb +0 -2
- data/lib/active_support/core_ext/range/include_range.rb +3 -1
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/range.rb +0 -2
- data/lib/active_support/core_ext/string/access.rb +95 -90
- data/lib/active_support/core_ext/string/conversions.rb +27 -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/string.rb +2 -3
- 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/calculations.rb +108 -184
- data/lib/active_support/core_ext/time/conversions.rb +27 -51
- 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/time.rb +5 -0
- data/lib/active_support/core_ext/uri.rb +13 -17
- data/lib/active_support/core_ext.rb +3 -2
- data/lib/active_support/dependencies/autoload.rb +47 -20
- data/lib/active_support/dependencies.rb +160 -141
- 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/deprecation.rb +39 -14
- 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 +127 -42
- 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/test_helper.rb +18 -15
- data/lib/active_support/log_subscriber.rb +35 -52
- data/lib/active_support/logger.rb +57 -0
- data/lib/active_support/logger_silence.rb +24 -0
- data/lib/active_support/message_encryptor.rb +38 -35
- data/lib/active_support/message_verifier.rb +9 -15
- data/lib/active_support/multibyte/chars.rb +80 -333
- data/lib/active_support/multibyte/unicode.rb +74 -64
- data/lib/active_support/multibyte.rb +5 -28
- data/lib/active_support/notifications/fanout.rb +112 -18
- data/lib/active_support/notifications/instrumenter.rb +33 -14
- data/lib/active_support/notifications.rb +79 -26
- data/lib/active_support/number_helper.rb +637 -0
- data/lib/active_support/ordered_hash.rb +8 -190
- data/lib/active_support/ordered_options.rb +21 -23
- data/lib/active_support/per_thread_registry.rb +52 -0
- 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/subscriber.rb +93 -0
- 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 +54 -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 +29 -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 +80 -43
- data/lib/active_support/values/time_zone.rb +81 -60
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +7 -6
- data/lib/active_support/xml_mini/jdom.rb +9 -11
- data/lib/active_support/xml_mini/libxml.rb +1 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +2 -3
- data/lib/active_support/xml_mini/nokogiri.rb +1 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +2 -3
- data/lib/active_support/xml_mini/rexml.rb +6 -8
- data/lib/active_support/xml_mini.rb +35 -17
- data/lib/active_support.rb +8 -21
- metadata +104 -72
- 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/rounding.rb +0 -19
- data/lib/active_support/core_ext/float.rb +0 -1
- 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/daemon.rb +0 -23
- data/lib/active_support/core_ext/process.rb +0 -1
- 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/string/xchar.rb +0 -18
- 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/jruby.rb +0 -115
- data/lib/active_support/testing/performance/rubinius.rb +0 -113
- 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/testing/performance/ruby.rb +0 -152
- data/lib/active_support/testing/performance.rb +0 -317
- data/lib/active_support/time/autoload.rb +0 -5
- data/lib/active_support/whiny_nil.rb +0 -24
|
@@ -4,7 +4,7 @@ require 'active_support/inflector/transliterate'
|
|
|
4
4
|
# String inflections define new methods on the String class to transform names for different purposes.
|
|
5
5
|
# For instance, you can figure out the name of a table from the name of a class.
|
|
6
6
|
#
|
|
7
|
-
#
|
|
7
|
+
# 'ScaleScore'.tableize # => "scale_scores"
|
|
8
8
|
#
|
|
9
9
|
class String
|
|
10
10
|
# Returns the plural form of the word in the string.
|
|
@@ -13,43 +13,55 @@ class String
|
|
|
13
13
|
# the singular form will be returned if <tt>count == 1</tt>.
|
|
14
14
|
# For any other value of +count+ the plural will be returned.
|
|
15
15
|
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
|
|
16
|
+
# If the optional parameter +locale+ is specified,
|
|
17
|
+
# the word will be pluralized as a word of that language.
|
|
18
|
+
# By default, this parameter is set to <tt>:en</tt>.
|
|
19
|
+
# You must define your own inflection rules for languages other than English.
|
|
20
|
+
#
|
|
21
|
+
# 'post'.pluralize # => "posts"
|
|
22
|
+
# 'octopus'.pluralize # => "octopi"
|
|
23
|
+
# 'sheep'.pluralize # => "sheep"
|
|
24
|
+
# 'words'.pluralize # => "words"
|
|
25
|
+
# 'the blue mailman'.pluralize # => "the blue mailmen"
|
|
26
|
+
# 'CamelOctopus'.pluralize # => "CamelOctopi"
|
|
27
|
+
# 'apple'.pluralize(1) # => "apple"
|
|
28
|
+
# 'apple'.pluralize(2) # => "apples"
|
|
29
|
+
# 'ley'.pluralize(:es) # => "leyes"
|
|
30
|
+
# 'ley'.pluralize(1, :es) # => "ley"
|
|
31
|
+
def pluralize(count = nil, locale = :en)
|
|
32
|
+
locale = count if count.is_a?(Symbol)
|
|
26
33
|
if count == 1
|
|
27
34
|
self
|
|
28
35
|
else
|
|
29
|
-
ActiveSupport::Inflector.pluralize(self)
|
|
36
|
+
ActiveSupport::Inflector.pluralize(self, locale)
|
|
30
37
|
end
|
|
31
38
|
end
|
|
32
39
|
|
|
33
40
|
# The reverse of +pluralize+, returns the singular form of a word in a string.
|
|
34
41
|
#
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
# If the optional parameter +locale+ is specified,
|
|
43
|
+
# the word will be singularized as a word of that language.
|
|
44
|
+
# By default, this parameter is set to <tt>:en</tt>.
|
|
45
|
+
# You must define your own inflection rules for languages other than English.
|
|
46
|
+
#
|
|
47
|
+
# 'posts'.singularize # => "post"
|
|
48
|
+
# 'octopi'.singularize # => "octopus"
|
|
49
|
+
# 'sheep'.singularize # => "sheep"
|
|
50
|
+
# 'word'.singularize # => "word"
|
|
51
|
+
# 'the blue mailmen'.singularize # => "the blue mailman"
|
|
52
|
+
# 'CamelOctopi'.singularize # => "CamelOctopus"
|
|
53
|
+
# 'leyes'.singularize(:es) # => "ley"
|
|
54
|
+
def singularize(locale = :en)
|
|
55
|
+
ActiveSupport::Inflector.singularize(self, locale)
|
|
43
56
|
end
|
|
44
57
|
|
|
45
58
|
# +constantize+ tries to find a declared constant with the name specified
|
|
46
59
|
# in the string. It raises a NameError when the name is not in CamelCase
|
|
47
60
|
# or is not initialized. See ActiveSupport::Inflector.constantize
|
|
48
61
|
#
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
# "blargle".constantize # => NameError: wrong constant name blargle
|
|
62
|
+
# 'Module'.constantize # => Module
|
|
63
|
+
# 'Class'.constantize # => Class
|
|
64
|
+
# 'blargle'.constantize # => NameError: wrong constant name blargle
|
|
53
65
|
def constantize
|
|
54
66
|
ActiveSupport::Inflector.constantize(self)
|
|
55
67
|
end
|
|
@@ -58,10 +70,9 @@ class String
|
|
|
58
70
|
# in the string. It returns nil when the name is not in CamelCase
|
|
59
71
|
# or is not initialized. See ActiveSupport::Inflector.safe_constantize
|
|
60
72
|
#
|
|
61
|
-
#
|
|
62
|
-
#
|
|
63
|
-
#
|
|
64
|
-
# "blargle".safe_constantize # => nil
|
|
73
|
+
# 'Module'.safe_constantize # => Module
|
|
74
|
+
# 'Class'.safe_constantize # => Class
|
|
75
|
+
# 'blargle'.safe_constantize # => nil
|
|
65
76
|
def safe_constantize
|
|
66
77
|
ActiveSupport::Inflector.safe_constantize(self)
|
|
67
78
|
end
|
|
@@ -71,14 +82,16 @@ class String
|
|
|
71
82
|
#
|
|
72
83
|
# +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
|
|
73
84
|
#
|
|
74
|
-
#
|
|
75
|
-
#
|
|
76
|
-
#
|
|
77
|
-
#
|
|
85
|
+
# 'active_record'.camelize # => "ActiveRecord"
|
|
86
|
+
# 'active_record'.camelize(:lower) # => "activeRecord"
|
|
87
|
+
# 'active_record/errors'.camelize # => "ActiveRecord::Errors"
|
|
88
|
+
# 'active_record/errors'.camelize(:lower) # => "activeRecord::Errors"
|
|
78
89
|
def camelize(first_letter = :upper)
|
|
79
90
|
case first_letter
|
|
80
|
-
|
|
81
|
-
|
|
91
|
+
when :upper
|
|
92
|
+
ActiveSupport::Inflector.camelize(self, true)
|
|
93
|
+
when :lower
|
|
94
|
+
ActiveSupport::Inflector.camelize(self, false)
|
|
82
95
|
end
|
|
83
96
|
end
|
|
84
97
|
alias_method :camelcase, :camelize
|
|
@@ -89,8 +102,8 @@ class String
|
|
|
89
102
|
#
|
|
90
103
|
# +titleize+ is also aliased as +titlecase+.
|
|
91
104
|
#
|
|
92
|
-
#
|
|
93
|
-
#
|
|
105
|
+
# 'man from the boondocks'.titleize # => "Man From The Boondocks"
|
|
106
|
+
# 'x-men: the last stand'.titleize # => "X Men: The Last Stand"
|
|
94
107
|
def titleize
|
|
95
108
|
ActiveSupport::Inflector.titleize(self)
|
|
96
109
|
end
|
|
@@ -100,23 +113,23 @@ class String
|
|
|
100
113
|
#
|
|
101
114
|
# +underscore+ will also change '::' to '/' to convert namespaces to paths.
|
|
102
115
|
#
|
|
103
|
-
#
|
|
104
|
-
#
|
|
116
|
+
# 'ActiveModel'.underscore # => "active_model"
|
|
117
|
+
# 'ActiveModel::Errors'.underscore # => "active_model/errors"
|
|
105
118
|
def underscore
|
|
106
119
|
ActiveSupport::Inflector.underscore(self)
|
|
107
120
|
end
|
|
108
121
|
|
|
109
122
|
# Replaces underscores with dashes in the string.
|
|
110
123
|
#
|
|
111
|
-
#
|
|
124
|
+
# 'puni_puni'.dasherize # => "puni-puni"
|
|
112
125
|
def dasherize
|
|
113
126
|
ActiveSupport::Inflector.dasherize(self)
|
|
114
127
|
end
|
|
115
128
|
|
|
116
129
|
# Removes the module part from the constant expression in the string.
|
|
117
130
|
#
|
|
118
|
-
#
|
|
119
|
-
#
|
|
131
|
+
# 'ActiveRecord::CoreExtensions::String::Inflections'.demodulize # => "Inflections"
|
|
132
|
+
# 'Inflections'.demodulize # => "Inflections"
|
|
120
133
|
#
|
|
121
134
|
# See also +deconstantize+.
|
|
122
135
|
def demodulize
|
|
@@ -125,11 +138,11 @@ class String
|
|
|
125
138
|
|
|
126
139
|
# Removes the rightmost segment from the constant expression in the string.
|
|
127
140
|
#
|
|
128
|
-
#
|
|
129
|
-
#
|
|
130
|
-
#
|
|
131
|
-
#
|
|
132
|
-
#
|
|
141
|
+
# 'Net::HTTP'.deconstantize # => "Net"
|
|
142
|
+
# '::Net::HTTP'.deconstantize # => "::Net"
|
|
143
|
+
# 'String'.deconstantize # => ""
|
|
144
|
+
# '::String'.deconstantize # => ""
|
|
145
|
+
# ''.deconstantize # => ""
|
|
133
146
|
#
|
|
134
147
|
# See also +demodulize+.
|
|
135
148
|
def deconstantize
|
|
@@ -138,8 +151,6 @@ class String
|
|
|
138
151
|
|
|
139
152
|
# Replaces special characters in a string so that it may be used as part of a 'pretty' URL.
|
|
140
153
|
#
|
|
141
|
-
# ==== Examples
|
|
142
|
-
#
|
|
143
154
|
# class Person
|
|
144
155
|
# def to_param
|
|
145
156
|
# "#{id}-#{name.parameterize}"
|
|
@@ -158,9 +169,9 @@ class String
|
|
|
158
169
|
# Creates the name of a table like Rails does for models to table names. This method
|
|
159
170
|
# uses the +pluralize+ method on the last word in the string.
|
|
160
171
|
#
|
|
161
|
-
#
|
|
162
|
-
#
|
|
163
|
-
#
|
|
172
|
+
# 'RawScaledScorer'.tableize # => "raw_scaled_scorers"
|
|
173
|
+
# 'egg_and_ham'.tableize # => "egg_and_hams"
|
|
174
|
+
# 'fancyCategory'.tableize # => "fancy_categories"
|
|
164
175
|
def tableize
|
|
165
176
|
ActiveSupport::Inflector.tableize(self)
|
|
166
177
|
end
|
|
@@ -169,12 +180,12 @@ class String
|
|
|
169
180
|
# Note that this returns a string and not a class. (To convert to an actual class
|
|
170
181
|
# follow +classify+ with +constantize+.)
|
|
171
182
|
#
|
|
172
|
-
#
|
|
173
|
-
#
|
|
183
|
+
# 'egg_and_hams'.classify # => "EggAndHam"
|
|
184
|
+
# 'posts'.classify # => "Post"
|
|
174
185
|
#
|
|
175
186
|
# Singular names are not handled correctly.
|
|
176
187
|
#
|
|
177
|
-
#
|
|
188
|
+
# 'business'.classify # => "Busines"
|
|
178
189
|
def classify
|
|
179
190
|
ActiveSupport::Inflector.classify(self)
|
|
180
191
|
end
|
|
@@ -182,8 +193,8 @@ class String
|
|
|
182
193
|
# Capitalizes the first word, turns underscores into spaces, and strips '_id'.
|
|
183
194
|
# Like +titleize+, this is meant for creating pretty output.
|
|
184
195
|
#
|
|
185
|
-
#
|
|
186
|
-
#
|
|
196
|
+
# 'employee_salary'.humanize # => "Employee salary"
|
|
197
|
+
# 'author_id'.humanize # => "Author"
|
|
187
198
|
def humanize
|
|
188
199
|
ActiveSupport::Inflector.humanize(self)
|
|
189
200
|
end
|
|
@@ -192,10 +203,9 @@ class String
|
|
|
192
203
|
# +separate_class_name_and_id_with_underscore+ sets whether
|
|
193
204
|
# the method should put '_' between the name and 'id'.
|
|
194
205
|
#
|
|
195
|
-
#
|
|
196
|
-
#
|
|
197
|
-
#
|
|
198
|
-
# "Admin::Post".foreign_key # => "post_id"
|
|
206
|
+
# 'Message'.foreign_key # => "message_id"
|
|
207
|
+
# 'Message'.foreign_key(false) # => "messageid"
|
|
208
|
+
# 'Admin::Post'.foreign_key # => "post_id"
|
|
199
209
|
def foreign_key(separate_class_name_and_id_with_underscore = true)
|
|
200
210
|
ActiveSupport::Inflector.foreign_key(self, separate_class_name_and_id_with_underscore)
|
|
201
211
|
end
|
|
@@ -2,9 +2,9 @@ require 'active_support/string_inquirer'
|
|
|
2
2
|
|
|
3
3
|
class String
|
|
4
4
|
# Wraps the current string in the <tt>ActiveSupport::StringInquirer</tt> class,
|
|
5
|
-
# which gives you a prettier way to test for equality.
|
|
5
|
+
# which gives you a prettier way to test for equality.
|
|
6
6
|
#
|
|
7
|
-
# env =
|
|
7
|
+
# env = 'production'.inquiry
|
|
8
8
|
# env.production? # => true
|
|
9
9
|
# env.development? # => false
|
|
10
10
|
def inquiry
|
|
@@ -2,71 +2,48 @@
|
|
|
2
2
|
require 'active_support/multibyte'
|
|
3
3
|
|
|
4
4
|
class String
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
# information about how to change the default Multibyte behavior see ActiveSupport::Multibyte.
|
|
39
|
-
def mb_chars
|
|
40
|
-
if ActiveSupport::Multibyte.proxy_class.consumes?(self)
|
|
41
|
-
ActiveSupport::Multibyte.proxy_class.new(self)
|
|
42
|
-
else
|
|
43
|
-
self
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def is_utf8?
|
|
48
|
-
case encoding
|
|
49
|
-
when Encoding::UTF_8
|
|
50
|
-
valid_encoding?
|
|
51
|
-
when Encoding::ASCII_8BIT, Encoding::US_ASCII
|
|
52
|
-
dup.force_encoding(Encoding::UTF_8).valid_encoding?
|
|
53
|
-
else
|
|
54
|
-
false
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
else
|
|
58
|
-
def mb_chars
|
|
59
|
-
if ActiveSupport::Multibyte.proxy_class.wants?(self)
|
|
60
|
-
ActiveSupport::Multibyte.proxy_class.new(self)
|
|
61
|
-
else
|
|
62
|
-
self
|
|
63
|
-
end
|
|
64
|
-
end
|
|
5
|
+
# == Multibyte proxy
|
|
6
|
+
#
|
|
7
|
+
# +mb_chars+ is a multibyte safe proxy for string methods.
|
|
8
|
+
#
|
|
9
|
+
# It creates and returns an instance of the ActiveSupport::Multibyte::Chars class which
|
|
10
|
+
# encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy
|
|
11
|
+
# class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsulated string.
|
|
12
|
+
#
|
|
13
|
+
# name = 'Claus Müller'
|
|
14
|
+
# name.reverse # => "rell??M sualC"
|
|
15
|
+
# name.length # => 13
|
|
16
|
+
#
|
|
17
|
+
# name.mb_chars.reverse.to_s # => "rellüM sualC"
|
|
18
|
+
# name.mb_chars.length # => 12
|
|
19
|
+
#
|
|
20
|
+
# == Method chaining
|
|
21
|
+
#
|
|
22
|
+
# All the methods on the Chars proxy which normally return a string will return a Chars object. This allows
|
|
23
|
+
# method chaining on the result of any of these methods.
|
|
24
|
+
#
|
|
25
|
+
# name.mb_chars.reverse.length # => 12
|
|
26
|
+
#
|
|
27
|
+
# == Interoperability and configuration
|
|
28
|
+
#
|
|
29
|
+
# The Chars object tries to be as interchangeable with String objects as possible: sorting and comparing between
|
|
30
|
+
# String and Char work like expected. The bang! methods change the internal string representation in the Chars
|
|
31
|
+
# object. Interoperability problems can be resolved easily with a +to_s+ call.
|
|
32
|
+
#
|
|
33
|
+
# For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars. For
|
|
34
|
+
# information about how to change the default Multibyte behavior see ActiveSupport::Multibyte.
|
|
35
|
+
def mb_chars
|
|
36
|
+
ActiveSupport::Multibyte.proxy_class.new(self)
|
|
37
|
+
end
|
|
65
38
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
39
|
+
def is_utf8?
|
|
40
|
+
case encoding
|
|
41
|
+
when Encoding::UTF_8
|
|
42
|
+
valid_encoding?
|
|
43
|
+
when Encoding::ASCII_8BIT, Encoding::US_ASCII
|
|
44
|
+
dup.force_encoding(Encoding::UTF_8).valid_encoding?
|
|
45
|
+
else
|
|
46
|
+
false
|
|
70
47
|
end
|
|
71
48
|
end
|
|
72
49
|
end
|
|
@@ -3,35 +3,25 @@ require 'active_support/core_ext/kernel/singleton_class'
|
|
|
3
3
|
|
|
4
4
|
class ERB
|
|
5
5
|
module Util
|
|
6
|
-
HTML_ESCAPE = { '&' => '&', '>' => '>', '<' => '<', '"' => '"', "'" => '&#
|
|
6
|
+
HTML_ESCAPE = { '&' => '&', '>' => '>', '<' => '<', '"' => '"', "'" => ''' }
|
|
7
7
|
JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003E', '<' => '\u003C' }
|
|
8
|
+
HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+));)/
|
|
9
|
+
JSON_ESCAPE_REGEXP = /[&"><]/
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
s
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
else
|
|
24
|
-
s.gsub(/[&"'><]/, HTML_ESCAPE).html_safe
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
else
|
|
28
|
-
def html_escape(s) #:nodoc:
|
|
29
|
-
s = s.to_s
|
|
30
|
-
if s.html_safe?
|
|
31
|
-
s
|
|
32
|
-
else
|
|
33
|
-
s.gsub(/[&"'><]/n) { |special| HTML_ESCAPE[special] }.html_safe
|
|
34
|
-
end
|
|
11
|
+
# A utility method for escaping HTML tag characters.
|
|
12
|
+
# This method is also aliased as <tt>h</tt>.
|
|
13
|
+
#
|
|
14
|
+
# In your ERB templates, use this method to escape any unsafe content. For example:
|
|
15
|
+
# <%=h @person.name %>
|
|
16
|
+
#
|
|
17
|
+
# puts html_escape('is a > 0 & a < 10?')
|
|
18
|
+
# # => is a > 0 & a < 10?
|
|
19
|
+
def html_escape(s)
|
|
20
|
+
s = s.to_s
|
|
21
|
+
if s.html_safe?
|
|
22
|
+
s
|
|
23
|
+
else
|
|
24
|
+
s.gsub(/[&"'><]/, HTML_ESCAPE).html_safe
|
|
35
25
|
end
|
|
36
26
|
end
|
|
37
27
|
|
|
@@ -44,10 +34,24 @@ class ERB
|
|
|
44
34
|
singleton_class.send(:remove_method, :html_escape)
|
|
45
35
|
module_function :html_escape
|
|
46
36
|
|
|
37
|
+
# A utility method for escaping HTML without affecting existing escaped entities.
|
|
38
|
+
#
|
|
39
|
+
# html_escape_once('1 < 2 & 3')
|
|
40
|
+
# # => "1 < 2 & 3"
|
|
41
|
+
#
|
|
42
|
+
# html_escape_once('<< Accept & Checkout')
|
|
43
|
+
# # => "<< Accept & Checkout"
|
|
44
|
+
def html_escape_once(s)
|
|
45
|
+
result = s.to_s.gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE)
|
|
46
|
+
s.html_safe? ? result.html_safe : result
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
module_function :html_escape_once
|
|
50
|
+
|
|
47
51
|
# A utility method for escaping HTML entities in JSON strings
|
|
48
52
|
# using \uXXXX JavaScript escape sequences for string literals:
|
|
49
53
|
#
|
|
50
|
-
# json_escape(
|
|
54
|
+
# json_escape('is a > 0 & a < 10?')
|
|
51
55
|
# # => is a \u003E 0 \u0026 a \u003C 10?
|
|
52
56
|
#
|
|
53
57
|
# Note that after this operation is performed the output is not
|
|
@@ -55,19 +59,11 @@ class ERB
|
|
|
55
59
|
#
|
|
56
60
|
# json_escape('{"name":"john","created_at":"2010-04-28T01:39:31Z","id":1}')
|
|
57
61
|
# # => {name:john,created_at:2010-04-28T01:39:31Z,id:1}
|
|
58
|
-
#
|
|
59
|
-
# This method is also aliased as +j+, and available as a helper
|
|
60
|
-
# in Rails templates:
|
|
61
|
-
#
|
|
62
|
-
# <%=j @person.to_json %>
|
|
63
|
-
#
|
|
64
62
|
def json_escape(s)
|
|
65
|
-
result = s.to_s.gsub(
|
|
63
|
+
result = s.to_s.gsub(JSON_ESCAPE_REGEXP, JSON_ESCAPE)
|
|
66
64
|
s.html_safe? ? result.html_safe : result
|
|
67
65
|
end
|
|
68
66
|
|
|
69
|
-
alias j json_escape
|
|
70
|
-
module_function :j
|
|
71
67
|
module_function :json_escape
|
|
72
68
|
end
|
|
73
69
|
end
|
|
@@ -86,26 +82,31 @@ end
|
|
|
86
82
|
|
|
87
83
|
module ActiveSupport #:nodoc:
|
|
88
84
|
class SafeBuffer < String
|
|
89
|
-
UNSAFE_STRING_METHODS =
|
|
85
|
+
UNSAFE_STRING_METHODS = %w(
|
|
86
|
+
capitalize chomp chop delete downcase gsub lstrip next reverse rstrip
|
|
87
|
+
slice squeeze strip sub succ swapcase tr tr_s upcase prepend
|
|
88
|
+
)
|
|
90
89
|
|
|
91
90
|
alias_method :original_concat, :concat
|
|
92
91
|
private :original_concat
|
|
93
92
|
|
|
94
93
|
class SafeConcatError < StandardError
|
|
95
94
|
def initialize
|
|
96
|
-
super
|
|
95
|
+
super 'Could not concatenate to the buffer because it is not html safe.'
|
|
97
96
|
end
|
|
98
97
|
end
|
|
99
98
|
|
|
100
99
|
def [](*args)
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
if html_safe?
|
|
104
|
-
new_safe_buffer = super
|
|
105
|
-
new_safe_buffer.instance_eval { @html_safe = true }
|
|
106
|
-
new_safe_buffer
|
|
100
|
+
if args.size < 2
|
|
101
|
+
super
|
|
107
102
|
else
|
|
108
|
-
|
|
103
|
+
if html_safe?
|
|
104
|
+
new_safe_buffer = super
|
|
105
|
+
new_safe_buffer.instance_eval { @html_safe = true }
|
|
106
|
+
new_safe_buffer
|
|
107
|
+
else
|
|
108
|
+
to_str[*args]
|
|
109
|
+
end
|
|
109
110
|
end
|
|
110
111
|
end
|
|
111
112
|
|
|
@@ -141,6 +142,18 @@ module ActiveSupport #:nodoc:
|
|
|
141
142
|
dup.concat(other)
|
|
142
143
|
end
|
|
143
144
|
|
|
145
|
+
def %(args)
|
|
146
|
+
args = Array(args).map do |arg|
|
|
147
|
+
if !html_safe? || arg.html_safe?
|
|
148
|
+
arg
|
|
149
|
+
else
|
|
150
|
+
ERB::Util.h(arg)
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
self.class.new(super(args))
|
|
155
|
+
end
|
|
156
|
+
|
|
144
157
|
def html_safe?
|
|
145
158
|
defined?(@html_safe) && @html_safe
|
|
146
159
|
end
|
|
@@ -157,11 +170,6 @@ module ActiveSupport #:nodoc:
|
|
|
157
170
|
coder.represent_scalar nil, to_str
|
|
158
171
|
end
|
|
159
172
|
|
|
160
|
-
def to_yaml(*args)
|
|
161
|
-
return super() if defined?(YAML::ENGINE) && !YAML::ENGINE.syck?
|
|
162
|
-
to_str.to_yaml(*args)
|
|
163
|
-
end
|
|
164
|
-
|
|
165
173
|
UNSAFE_STRING_METHODS.each do |unsafe_method|
|
|
166
174
|
if 'String'.respond_to?(unsafe_method)
|
|
167
175
|
class_eval <<-EOT, __FILE__, __LINE__ + 1
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'active_support/core_ext/time/zones'
|
|
2
|
+
|
|
3
|
+
class String
|
|
4
|
+
# Converts String to a TimeWithZone in the current zone if Time.zone or Time.zone_default
|
|
5
|
+
# is set, otherwise converts String to a Time via String#to_time
|
|
6
|
+
def in_time_zone(zone = ::Time.zone)
|
|
7
|
+
if zone
|
|
8
|
+
::Time.find_zone!(zone).parse(self)
|
|
9
|
+
else
|
|
10
|
+
to_time
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -4,11 +4,10 @@ require 'active_support/core_ext/string/multibyte'
|
|
|
4
4
|
require 'active_support/core_ext/string/starts_ends_with'
|
|
5
5
|
require 'active_support/core_ext/string/inflections'
|
|
6
6
|
require 'active_support/core_ext/string/access'
|
|
7
|
-
require 'active_support/core_ext/string/xchar'
|
|
8
7
|
require 'active_support/core_ext/string/behavior'
|
|
9
|
-
require 'active_support/core_ext/string/interpolation'
|
|
10
8
|
require 'active_support/core_ext/string/output_safety'
|
|
11
9
|
require 'active_support/core_ext/string/exclude'
|
|
12
|
-
require 'active_support/core_ext/string/encoding'
|
|
13
10
|
require 'active_support/core_ext/string/strip'
|
|
14
11
|
require 'active_support/core_ext/string/inquiry'
|
|
12
|
+
require 'active_support/core_ext/string/indent'
|
|
13
|
+
require 'active_support/core_ext/string/zones'
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
class Thread
|
|
2
|
+
LOCK = Mutex.new # :nodoc:
|
|
3
|
+
|
|
4
|
+
# Returns the value of a thread local variable that has been set. Note that
|
|
5
|
+
# these are different than fiber local values.
|
|
6
|
+
#
|
|
7
|
+
# Thread local values are carried along with threads, and do not respect
|
|
8
|
+
# fibers. For example:
|
|
9
|
+
#
|
|
10
|
+
# Thread.new {
|
|
11
|
+
# Thread.current.thread_variable_set("foo", "bar") # set a thread local
|
|
12
|
+
# Thread.current["foo"] = "bar" # set a fiber local
|
|
13
|
+
#
|
|
14
|
+
# Fiber.new {
|
|
15
|
+
# Fiber.yield [
|
|
16
|
+
# Thread.current.thread_variable_get("foo"), # get the thread local
|
|
17
|
+
# Thread.current["foo"], # get the fiber local
|
|
18
|
+
# ]
|
|
19
|
+
# }.resume
|
|
20
|
+
# }.join.value # => ['bar', nil]
|
|
21
|
+
#
|
|
22
|
+
# The value <tt>"bar"</tt> is returned for the thread local, where +nil+ is returned
|
|
23
|
+
# for the fiber local. The fiber is executed in the same thread, so the
|
|
24
|
+
# thread local values are available.
|
|
25
|
+
def thread_variable_get(key)
|
|
26
|
+
locals[key.to_sym]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Sets a thread local with +key+ to +value+. Note that these are local to
|
|
30
|
+
# threads, and not to fibers. Please see Thread#thread_variable_get for
|
|
31
|
+
# more information.
|
|
32
|
+
def thread_variable_set(key, value)
|
|
33
|
+
locals[key.to_sym] = value
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Returns an an array of the names of the thread-local variables (as Symbols).
|
|
37
|
+
#
|
|
38
|
+
# thr = Thread.new do
|
|
39
|
+
# Thread.current.thread_variable_set(:cat, 'meow')
|
|
40
|
+
# Thread.current.thread_variable_set("dog", 'woof')
|
|
41
|
+
# end
|
|
42
|
+
# thr.join #=> #<Thread:0x401b3f10 dead>
|
|
43
|
+
# thr.thread_variables #=> [:dog, :cat]
|
|
44
|
+
#
|
|
45
|
+
# Note that these are not fiber local variables. Please see Thread#thread_variable_get
|
|
46
|
+
# for more details.
|
|
47
|
+
def thread_variables
|
|
48
|
+
locals.keys
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Returns <tt>true</tt> if the given string (or symbol) exists as a
|
|
52
|
+
# thread-local variable.
|
|
53
|
+
#
|
|
54
|
+
# me = Thread.current
|
|
55
|
+
# me.thread_variable_set(:oliver, "a")
|
|
56
|
+
# me.thread_variable?(:oliver) #=> true
|
|
57
|
+
# me.thread_variable?(:stanley) #=> false
|
|
58
|
+
#
|
|
59
|
+
# Note that these are not fiber local variables. Please see Thread#thread_variable_get
|
|
60
|
+
# for more details.
|
|
61
|
+
def thread_variable?(key)
|
|
62
|
+
locals.has_key?(key.to_sym)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
def locals
|
|
68
|
+
if defined?(@locals)
|
|
69
|
+
@locals
|
|
70
|
+
else
|
|
71
|
+
LOCK.synchronize { @locals ||= {} }
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end unless Thread.instance_methods.include?(:thread_variable_set)
|