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
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'active_support/core_ext/object/duplicable'
|
2
|
+
|
3
|
+
class Object
|
4
|
+
# Returns a deep copy of object if it's duplicable. If it's
|
5
|
+
# not duplicable, returns +self+.
|
6
|
+
#
|
7
|
+
# object = Object.new
|
8
|
+
# dup = object.deep_dup
|
9
|
+
# dup.instance_variable_set(:@a, 1)
|
10
|
+
#
|
11
|
+
# object.instance_variable_defined?(:@a) #=> false
|
12
|
+
# dup.instance_variable_defined?(:@a) #=> true
|
13
|
+
def deep_dup
|
14
|
+
duplicable? ? dup : self
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Array
|
19
|
+
# Returns a deep copy of array.
|
20
|
+
#
|
21
|
+
# array = [1, [2, 3]]
|
22
|
+
# dup = array.deep_dup
|
23
|
+
# dup[1][2] = 4
|
24
|
+
#
|
25
|
+
# array[1][2] #=> nil
|
26
|
+
# dup[1][2] #=> 4
|
27
|
+
def deep_dup
|
28
|
+
map { |it| it.deep_dup }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Hash
|
33
|
+
# Returns a deep copy of hash.
|
34
|
+
#
|
35
|
+
# hash = { a: { b: 'b' } }
|
36
|
+
# dup = hash.deep_dup
|
37
|
+
# dup[:a][:c] = 'c'
|
38
|
+
#
|
39
|
+
# hash[:a][:c] #=> nil
|
40
|
+
# dup[:a][:c] #=> "c"
|
41
|
+
def deep_dup
|
42
|
+
each_with_object(dup) do |(key, value), hash|
|
43
|
+
hash[key.deep_dup] = value.deep_dup
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -19,7 +19,7 @@
|
|
19
19
|
class Object
|
20
20
|
# Can you safely dup this object?
|
21
21
|
#
|
22
|
-
# False for +nil+, +false+, +true+,
|
22
|
+
# False for +nil+, +false+, +true+, symbol, and number objects;
|
23
23
|
# true otherwise.
|
24
24
|
def duplicable?
|
25
25
|
true
|
@@ -31,7 +31,6 @@ class NilClass
|
|
31
31
|
#
|
32
32
|
# nil.duplicable? # => false
|
33
33
|
# nil.dup # => TypeError: can't dup NilClass
|
34
|
-
#
|
35
34
|
def duplicable?
|
36
35
|
false
|
37
36
|
end
|
@@ -42,7 +41,6 @@ class FalseClass
|
|
42
41
|
#
|
43
42
|
# false.duplicable? # => false
|
44
43
|
# false.dup # => TypeError: can't dup FalseClass
|
45
|
-
#
|
46
44
|
def duplicable?
|
47
45
|
false
|
48
46
|
end
|
@@ -53,7 +51,6 @@ class TrueClass
|
|
53
51
|
#
|
54
52
|
# true.duplicable? # => false
|
55
53
|
# true.dup # => TypeError: can't dup TrueClass
|
56
|
-
#
|
57
54
|
def duplicable?
|
58
55
|
false
|
59
56
|
end
|
@@ -64,7 +61,6 @@ class Symbol
|
|
64
61
|
#
|
65
62
|
# :my_symbol.duplicable? # => false
|
66
63
|
# :my_symbol.dup # => TypeError: can't dup Symbol
|
67
|
-
#
|
68
64
|
def duplicable?
|
69
65
|
false
|
70
66
|
end
|
@@ -75,31 +71,6 @@ class Numeric
|
|
75
71
|
#
|
76
72
|
# 3.duplicable? # => false
|
77
73
|
# 3.dup # => TypeError: can't dup Fixnum
|
78
|
-
#
|
79
|
-
def duplicable?
|
80
|
-
false
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
class Class
|
85
|
-
# Classes are not duplicable:
|
86
|
-
#
|
87
|
-
# c = Class.new # => #<Class:0x10328fd80>
|
88
|
-
# c.dup # => #<Class:0x10328fd80>
|
89
|
-
#
|
90
|
-
# Note +dup+ returned the same class object.
|
91
|
-
def duplicable?
|
92
|
-
false
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
class Module
|
97
|
-
# Modules are not duplicable:
|
98
|
-
#
|
99
|
-
# m = Module.new # => #<Module:0x10328b6e0>
|
100
|
-
# m.dup # => #<Module:0x10328b6e0>
|
101
|
-
#
|
102
|
-
# Note +dup+ returned the same module object.
|
103
74
|
def duplicable?
|
104
75
|
false
|
105
76
|
end
|
@@ -2,11 +2,11 @@ class Object
|
|
2
2
|
# Returns true if this object is included in the argument(s). Argument must be
|
3
3
|
# any object which responds to +#include?+ or optionally, multiple arguments can be passed in. Usage:
|
4
4
|
#
|
5
|
-
# characters = [
|
6
|
-
#
|
7
|
-
#
|
8
|
-
# character =
|
9
|
-
# character.in?(
|
5
|
+
# characters = ['Konata', 'Kagami', 'Tsukasa']
|
6
|
+
# 'Konata'.in?(characters) # => true
|
7
|
+
#
|
8
|
+
# character = 'Konata'
|
9
|
+
# character.in?('Konata', 'Kagami', 'Tsukasa') # => true
|
10
10
|
#
|
11
11
|
# This will throw an ArgumentError if a single argument is passed in and it doesn't respond
|
12
12
|
# to +#include?+.
|
@@ -18,7 +18,7 @@ class Object
|
|
18
18
|
if another_object.respond_to? :include?
|
19
19
|
another_object.include? self
|
20
20
|
else
|
21
|
-
raise ArgumentError.new
|
21
|
+
raise ArgumentError.new 'The single parameter passed to #in? must respond to #include?'
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class Object
|
2
|
-
# Returns a hash that maps instance variable names without "@" to their
|
3
|
-
# corresponding values.
|
2
|
+
# Returns a hash with string keys that maps instance variable names without "@" to their
|
3
|
+
# corresponding values.
|
4
4
|
#
|
5
5
|
# class C
|
6
6
|
# def initialize(x, y)
|
@@ -9,12 +9,11 @@ class Object
|
|
9
9
|
# end
|
10
10
|
#
|
11
11
|
# C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
|
12
|
-
def instance_values
|
13
|
-
Hash[instance_variables.map { |name| [name
|
12
|
+
def instance_values
|
13
|
+
Hash[instance_variables.map { |name| [name[1..-1], instance_variable_get(name)] }]
|
14
14
|
end
|
15
15
|
|
16
|
-
# Returns an array of instance variable names including "@".
|
17
|
-
# both in Ruby 1.8 and 1.9.
|
16
|
+
# Returns an array of instance variable names as strings including "@".
|
18
17
|
#
|
19
18
|
# class C
|
20
19
|
# def initialize(x, y)
|
@@ -23,11 +22,7 @@ class Object
|
|
23
22
|
# end
|
24
23
|
#
|
25
24
|
# C.new(0, 1).instance_variable_names # => ["@y", "@x"]
|
26
|
-
|
27
|
-
|
28
|
-
instance_variables.map { |var| var.to_s }
|
29
|
-
end
|
30
|
-
else
|
31
|
-
alias_method :instance_variable_names, :instance_variables
|
25
|
+
def instance_variable_names
|
26
|
+
instance_variables.map { |var| var.to_s }
|
32
27
|
end
|
33
28
|
end
|
@@ -6,18 +6,21 @@ class Object
|
|
6
6
|
end
|
7
7
|
|
8
8
|
class NilClass
|
9
|
+
# Returns +self+.
|
9
10
|
def to_param
|
10
11
|
self
|
11
12
|
end
|
12
13
|
end
|
13
14
|
|
14
15
|
class TrueClass
|
16
|
+
# Returns +self+.
|
15
17
|
def to_param
|
16
18
|
self
|
17
19
|
end
|
18
20
|
end
|
19
21
|
|
20
22
|
class FalseClass
|
23
|
+
# Returns +self+.
|
21
24
|
def to_param
|
22
25
|
self
|
23
26
|
end
|
@@ -35,12 +38,12 @@ class Hash
|
|
35
38
|
# Returns a string representation of the receiver suitable for use as a URL
|
36
39
|
# query string:
|
37
40
|
#
|
38
|
-
# {:
|
41
|
+
# {name: 'David', nationality: 'Danish'}.to_param
|
39
42
|
# # => "name=David&nationality=Danish"
|
40
43
|
#
|
41
44
|
# An optional namespace can be passed to enclose the param names:
|
42
45
|
#
|
43
|
-
# {:
|
46
|
+
# {name: 'David', nationality: 'Danish'}.to_param('user')
|
44
47
|
# # => "user[name]=David&user[nationality]=Danish"
|
45
48
|
#
|
46
49
|
# The string pairs "key=value" that conform the query string
|
@@ -1,39 +1,58 @@
|
|
1
1
|
class Object
|
2
|
-
# Invokes the method
|
3
|
-
#
|
2
|
+
# Invokes the public method whose name goes as first argument just like
|
3
|
+
# +public_send+ does, except that if the receiver does not respond to it the
|
4
|
+
# call returns +nil+ rather than raising an exception.
|
4
5
|
#
|
5
|
-
#
|
6
|
-
# and +nil+ will be returned instead, if the receiving object is a +nil+ object or NilClass.
|
6
|
+
# This method is defined to be able to write
|
7
7
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# Please also note that +try+ is defined on +Object+, therefore it won't work with
|
11
|
-
# subclasses of +BasicObject+. For example, using try with +SimpleDelegator+ will
|
12
|
-
# delegate +try+ to target instead of calling it on delegator itself.
|
8
|
+
# @person.try(:name)
|
13
9
|
#
|
14
|
-
#
|
10
|
+
# instead of
|
15
11
|
#
|
16
|
-
# Without +try+
|
17
|
-
# @person && @person.name
|
18
|
-
# or
|
19
12
|
# @person ? @person.name : nil
|
20
13
|
#
|
21
|
-
#
|
22
|
-
#
|
14
|
+
# +try+ returns +nil+ when called on +nil+ regardless of whether it responds
|
15
|
+
# to the method:
|
16
|
+
#
|
17
|
+
# nil.try(:to_i) # => nil, rather than 0
|
18
|
+
#
|
19
|
+
# Arguments and blocks are forwarded to the method if invoked:
|
20
|
+
#
|
21
|
+
# @posts.try(:each_slice, 2) do |a, b|
|
22
|
+
# ...
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# The number of arguments in the signature must match. If the object responds
|
26
|
+
# to the method the call is attempted and +ArgumentError+ is still raised
|
27
|
+
# otherwise.
|
28
|
+
#
|
29
|
+
# If +try+ is called without arguments it yields the receiver to a given
|
30
|
+
# block unless it is +nil+:
|
23
31
|
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
32
|
+
# @person.try do |p|
|
33
|
+
# ...
|
34
|
+
# end
|
27
35
|
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
|
31
|
-
# +
|
36
|
+
# Please also note that +try+ is defined on +Object+, therefore it won't work
|
37
|
+
# with instances of classes that do not have +Object+ among their ancestors,
|
38
|
+
# like direct subclasses of +BasicObject+. For example, using +try+ with
|
39
|
+
# +SimpleDelegator+ will delegate +try+ to the target instead of calling it on
|
40
|
+
# delegator itself.
|
32
41
|
def try(*a, &b)
|
33
42
|
if a.empty? && block_given?
|
34
43
|
yield self
|
35
44
|
else
|
36
|
-
|
45
|
+
public_send(*a, &b) if respond_to?(a.first)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Same as #try, but will raise a NoMethodError exception if the receiving is not nil and
|
50
|
+
# does not implemented the tried method.
|
51
|
+
def try!(*a, &b)
|
52
|
+
if a.empty? && block_given?
|
53
|
+
yield self
|
54
|
+
else
|
55
|
+
public_send(*a, &b)
|
37
56
|
end
|
38
57
|
end
|
39
58
|
end
|
@@ -42,8 +61,6 @@ class NilClass
|
|
42
61
|
# Calling +try+ on +nil+ always returns +nil+.
|
43
62
|
# It becomes specially helpful when navigating through associations that may return +nil+.
|
44
63
|
#
|
45
|
-
# === Examples
|
46
|
-
#
|
47
64
|
# nil.try(:name) # => nil
|
48
65
|
#
|
49
66
|
# Without +try+
|
@@ -54,4 +71,8 @@ class NilClass
|
|
54
71
|
def try(*args)
|
55
72
|
nil
|
56
73
|
end
|
74
|
+
|
75
|
+
def try!(*args)
|
76
|
+
nil
|
77
|
+
end
|
57
78
|
end
|
@@ -10,16 +10,16 @@ class Object
|
|
10
10
|
# Without <tt>with_options></tt>, this code contains duplication:
|
11
11
|
#
|
12
12
|
# class Account < ActiveRecord::Base
|
13
|
-
# has_many :customers, :
|
14
|
-
# has_many :products, :
|
15
|
-
# has_many :invoices, :
|
16
|
-
# has_many :expenses, :
|
13
|
+
# has_many :customers, dependent: :destroy
|
14
|
+
# has_many :products, dependent: :destroy
|
15
|
+
# has_many :invoices, dependent: :destroy
|
16
|
+
# has_many :expenses, dependent: :destroy
|
17
17
|
# end
|
18
18
|
#
|
19
19
|
# Using <tt>with_options</tt>, we can remove the duplication:
|
20
20
|
#
|
21
21
|
# class Account < ActiveRecord::Base
|
22
|
-
# with_options :
|
22
|
+
# with_options dependent: :destroy do |assoc|
|
23
23
|
# assoc.has_many :customers
|
24
24
|
# assoc.has_many :products
|
25
25
|
# assoc.has_many :invoices
|
@@ -29,14 +29,13 @@ class Object
|
|
29
29
|
#
|
30
30
|
# It can also be used with an explicit receiver:
|
31
31
|
#
|
32
|
-
# I18n.with_options :
|
32
|
+
# I18n.with_options locale: user.locale, scope: 'newsletter' do |i18n|
|
33
33
|
# subject i18n.t :subject
|
34
|
-
# body i18n.t :body, :
|
34
|
+
# body i18n.t :body, user_name: user.name
|
35
35
|
# end
|
36
36
|
#
|
37
37
|
# <tt>with_options</tt> can also be nested since the call is forwarded to its receiver.
|
38
38
|
# Each nesting level will merge inherited defaults in addition to their own.
|
39
|
-
#
|
40
39
|
def with_options(options)
|
41
40
|
yield ActiveSupport::OptionMerger.new(self, options)
|
42
41
|
end
|
@@ -1,7 +1,10 @@
|
|
1
1
|
require "active_support/core_ext/kernel/singleton_class"
|
2
|
+
require "active_support/deprecation"
|
2
3
|
|
3
4
|
class Proc #:nodoc:
|
4
5
|
def bind(object)
|
6
|
+
ActiveSupport::Deprecation.warn 'Proc#bind is deprecated and will be removed in future versions'
|
7
|
+
|
5
8
|
block, time = self, Time.now
|
6
9
|
object.class_eval do
|
7
10
|
method_name = "__bind_#{time.to_i}_#{time.usec}"
|
@@ -5,7 +5,7 @@ class Range
|
|
5
5
|
# (1..5).include?(2..6) # => false
|
6
6
|
#
|
7
7
|
# The native Range#include? behavior is untouched.
|
8
|
-
# (
|
8
|
+
# ('a'..'f').include?('c') # => true
|
9
9
|
# (5..9).include?(11) # => false
|
10
10
|
def include_with_range?(value)
|
11
11
|
if value.is_a?(::Range)
|
@@ -6,9 +6,9 @@ require 'active_support/core_ext/string/inflections'
|
|
6
6
|
require 'active_support/core_ext/string/access'
|
7
7
|
require 'active_support/core_ext/string/xchar'
|
8
8
|
require 'active_support/core_ext/string/behavior'
|
9
|
-
require 'active_support/core_ext/string/interpolation'
|
10
9
|
require 'active_support/core_ext/string/output_safety'
|
11
10
|
require 'active_support/core_ext/string/exclude'
|
12
|
-
require 'active_support/core_ext/string/encoding'
|
13
11
|
require 'active_support/core_ext/string/strip'
|
14
12
|
require 'active_support/core_ext/string/inquiry'
|
13
|
+
require 'active_support/core_ext/string/indent'
|
14
|
+
require 'active_support/core_ext/string/zones'
|
@@ -1,99 +1,104 @@
|
|
1
|
-
require "active_support/multibyte"
|
2
|
-
|
3
1
|
class String
|
4
|
-
|
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
|
-
mb_chars[0..position].to_s
|
33
|
-
end
|
34
|
-
|
35
|
-
# Returns the first character of the string or the first +limit+ characters.
|
36
|
-
#
|
37
|
-
# Examples:
|
38
|
-
# "hello".first # => "h"
|
39
|
-
# "hello".first(2) # => "he"
|
40
|
-
# "hello".first(10) # => "hello"
|
41
|
-
def first(limit = 1)
|
42
|
-
if limit == 0
|
43
|
-
''
|
44
|
-
elsif limit >= size
|
45
|
-
self
|
46
|
-
else
|
47
|
-
mb_chars[0...limit].to_s
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
# Returns the last character of the string or the last +limit+ characters.
|
52
|
-
#
|
53
|
-
# Examples:
|
54
|
-
# "hello".last # => "o"
|
55
|
-
# "hello".last(2) # => "lo"
|
56
|
-
# "hello".last(10) # => "hello"
|
57
|
-
def last(limit = 1)
|
58
|
-
if limit == 0
|
59
|
-
''
|
60
|
-
elsif limit >= size
|
61
|
-
self
|
62
|
-
else
|
63
|
-
mb_chars[(-limit)..-1].to_s
|
64
|
-
end
|
65
|
-
end
|
66
|
-
else
|
67
|
-
def at(position)
|
68
|
-
self[position]
|
69
|
-
end
|
2
|
+
# If you pass a single Fixnum, returns a substring of one character at that
|
3
|
+
# position. The first character of the string is at position 0, the next at
|
4
|
+
# position 1, and so on. If a range is supplied, a substring containing
|
5
|
+
# characters at offsets given by the range is returned. In both cases, if an
|
6
|
+
# offset is negative, it is counted from the end of the string. Returns nil
|
7
|
+
# if the initial offset falls outside the string. Returns an empty string if
|
8
|
+
# the beginning of the range is greater than the end of the string.
|
9
|
+
#
|
10
|
+
# str = "hello"
|
11
|
+
# str.at(0) #=> "h"
|
12
|
+
# str.at(1..3) #=> "ell"
|
13
|
+
# str.at(-2) #=> "l"
|
14
|
+
# str.at(-2..-1) #=> "lo"
|
15
|
+
# str.at(5) #=> nil
|
16
|
+
# str.at(5..-1) #=> ""
|
17
|
+
#
|
18
|
+
# If a Regexp is given, the matching portion of the string is returned.
|
19
|
+
# If a String is given, that given string is returned if it occurs in
|
20
|
+
# the string. In both cases, nil is returned if there is no match.
|
21
|
+
#
|
22
|
+
# str = "hello"
|
23
|
+
# str.at(/lo/) #=> "lo"
|
24
|
+
# str.at(/ol/) #=> nil
|
25
|
+
# str.at("lo") #=> "lo"
|
26
|
+
# str.at("ol") #=> nil
|
27
|
+
def at(position)
|
28
|
+
self[position]
|
29
|
+
end
|
70
30
|
|
71
|
-
|
72
|
-
|
73
|
-
|
31
|
+
# Returns a substring from the given position to the end of the string.
|
32
|
+
# If the position is negative, it is counted from the end of the string.
|
33
|
+
#
|
34
|
+
# str = "hello"
|
35
|
+
# str.from(0) #=> "hello"
|
36
|
+
# str.from(3) #=> "lo"
|
37
|
+
# str.from(-2) #=> "lo"
|
38
|
+
#
|
39
|
+
# You can mix it with +to+ method and do fun things like:
|
40
|
+
#
|
41
|
+
# str = "hello"
|
42
|
+
# str.from(0).to(-1) #=> "hello"
|
43
|
+
# str.from(1).to(-2) #=> "ell"
|
44
|
+
def from(position)
|
45
|
+
self[position..-1]
|
46
|
+
end
|
74
47
|
|
75
|
-
|
76
|
-
|
77
|
-
|
48
|
+
# Returns a substring from the beginning of the string to the given position.
|
49
|
+
# If the position is negative, it is counted from the end of the string.
|
50
|
+
#
|
51
|
+
# str = "hello"
|
52
|
+
# str.to(0) #=> "h"
|
53
|
+
# str.to(3) #=> "hell"
|
54
|
+
# str.to(-2) #=> "hell"
|
55
|
+
#
|
56
|
+
# You can mix it with +from+ method and do fun things like:
|
57
|
+
#
|
58
|
+
# str = "hello"
|
59
|
+
# str.from(0).to(-1) #=> "hello"
|
60
|
+
# str.from(1).to(-2) #=> "ell"
|
61
|
+
def to(position)
|
62
|
+
self[0..position]
|
63
|
+
end
|
78
64
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
65
|
+
# Returns the first character. If a limit is supplied, returns a substring
|
66
|
+
# from the beginning of the string until it reaches the limit value. If the
|
67
|
+
# given limit is greater than or equal to the string length, returns self.
|
68
|
+
#
|
69
|
+
# str = "hello"
|
70
|
+
# str.first #=> "h"
|
71
|
+
# str.first(1) #=> "h"
|
72
|
+
# str.first(2) #=> "he"
|
73
|
+
# str.first(0) #=> ""
|
74
|
+
# str.first(6) #=> "hello"
|
75
|
+
def first(limit = 1)
|
76
|
+
if limit == 0
|
77
|
+
''
|
78
|
+
elsif limit >= size
|
79
|
+
self
|
80
|
+
else
|
81
|
+
to(limit - 1)
|
87
82
|
end
|
83
|
+
end
|
88
84
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
85
|
+
# Returns the last character of the string. If a limit is supplied, returns a substring
|
86
|
+
# from the end of the string until it reaches the limit value (counting backwards). If
|
87
|
+
# the given limit is greater than or equal to the string length, returns self.
|
88
|
+
#
|
89
|
+
# str = "hello"
|
90
|
+
# str.last #=> "o"
|
91
|
+
# str.last(1) #=> "o"
|
92
|
+
# str.last(2) #=> "lo"
|
93
|
+
# str.last(0) #=> ""
|
94
|
+
# str.last(6) #=> "hello"
|
95
|
+
def last(limit = 1)
|
96
|
+
if limit == 0
|
97
|
+
''
|
98
|
+
elsif limit >= size
|
99
|
+
self
|
100
|
+
else
|
101
|
+
from(-limit)
|
97
102
|
end
|
98
103
|
end
|
99
104
|
end
|