activesupport 3.1.0 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/CHANGELOG.md +798 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +13 -7
- data/lib/active_support/array_inquirer.rb +44 -0
- data/lib/active_support/backtrace_cleaner.rb +38 -34
- data/lib/active_support/benchmarkable.rb +17 -28
- data/lib/active_support/cache/file_store.rb +85 -70
- data/lib/active_support/cache/mem_cache_store.rb +75 -66
- data/lib/active_support/cache/memory_store.rb +31 -23
- data/lib/active_support/cache/null_store.rb +41 -0
- data/lib/active_support/cache/strategy/local_cache.rb +73 -70
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +44 -0
- data/lib/active_support/cache.rb +360 -294
- data/lib/active_support/callbacks.rb +563 -393
- data/lib/active_support/concern.rb +42 -34
- data/lib/active_support/concurrency/latch.rb +19 -0
- data/lib/active_support/concurrency/share_lock.rb +186 -0
- data/lib/active_support/configurable.rb +70 -12
- data/lib/active_support/core_ext/array/access.rb +53 -9
- data/lib/active_support/core_ext/array/conversions.rb +109 -62
- data/lib/active_support/core_ext/array/extract_options.rb +2 -2
- data/lib/active_support/core_ext/array/grouping.rb +39 -32
- data/lib/active_support/core_ext/array/inquiry.rb +17 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +7 -0
- data/lib/active_support/core_ext/array/wrap.rb +16 -18
- data/lib/active_support/core_ext/array.rb +2 -2
- data/lib/active_support/core_ext/benchmark.rb +7 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -36
- data/lib/active_support/core_ext/class/attribute.rb +47 -34
- data/lib/active_support/core_ext/class/attribute_accessors.rb +4 -79
- data/lib/active_support/core_ext/class/subclasses.rb +12 -7
- data/lib/active_support/core_ext/class.rb +0 -3
- data/lib/active_support/core_ext/date/blank.rb +12 -0
- data/lib/active_support/core_ext/date/calculations.rb +57 -167
- data/lib/active_support/core_ext/date/conversions.rb +31 -42
- data/lib/active_support/core_ext/date/zones.rb +2 -10
- data/lib/active_support/core_ext/date.rb +5 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +335 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +1 -0
- data/lib/active_support/core_ext/date_time/blank.rb +12 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +132 -65
- data/lib/active_support/core_ext/date_time/compatibility.rb +5 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +36 -34
- data/lib/active_support/core_ext/date_time.rb +5 -0
- data/lib/active_support/core_ext/digest/uuid.rb +51 -0
- data/lib/active_support/core_ext/enumerable.rb +81 -74
- data/lib/active_support/core_ext/file/atomic.rb +53 -26
- data/lib/active_support/core_ext/file.rb +0 -1
- data/lib/active_support/core_ext/hash/compact.rb +20 -0
- data/lib/active_support/core_ext/hash/conversions.rb +175 -70
- data/lib/active_support/core_ext/hash/deep_merge.rb +30 -8
- data/lib/active_support/core_ext/hash/except.rb +11 -12
- data/lib/active_support/core_ext/hash/indifferent_access.rb +7 -8
- data/lib/active_support/core_ext/hash/keys.rb +147 -24
- data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -3
- data/lib/active_support/core_ext/hash/slice.rb +22 -14
- data/lib/active_support/core_ext/hash/transform_values.rb +29 -0
- data/lib/active_support/core_ext/hash.rb +2 -2
- data/lib/active_support/core_ext/integer/inflections.rb +13 -1
- data/lib/active_support/core_ext/integer/multiple.rb +4 -0
- data/lib/active_support/core_ext/integer/time.rb +12 -22
- data/lib/active_support/core_ext/kernel/agnostics.rb +2 -2
- data/lib/active_support/core_ext/kernel/concern.rb +12 -0
- data/lib/active_support/core_ext/kernel/debugger.rb +2 -15
- data/lib/active_support/core_ext/kernel/reporting.rb +12 -62
- data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -7
- data/lib/active_support/core_ext/kernel.rb +2 -3
- data/lib/active_support/core_ext/load_error.rb +14 -7
- data/lib/active_support/core_ext/marshal.rb +22 -0
- data/lib/active_support/core_ext/module/aliasing.rb +16 -12
- data/lib/active_support/core_ext/module/anonymous.rb +12 -8
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
- data/lib/active_support/core_ext/module/attribute_accessors.rb +165 -13
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
- data/lib/active_support/core_ext/module/concerning.rb +135 -0
- data/lib/active_support/core_ext/module/delegation.rb +141 -68
- data/lib/active_support/core_ext/module/deprecation.rb +17 -3
- data/lib/active_support/core_ext/module/introspection.rb +9 -31
- data/lib/active_support/core_ext/module/method_transplanting.rb +3 -0
- data/lib/active_support/core_ext/module/qualified_const.rb +70 -0
- data/lib/active_support/core_ext/module/reachable.rb +1 -3
- data/lib/active_support/core_ext/module/remove_method.rb +24 -5
- data/lib/active_support/core_ext/module.rb +3 -3
- data/lib/active_support/core_ext/name_error.rb +15 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +20 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +145 -0
- data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
- data/lib/active_support/core_ext/numeric/time.rb +31 -36
- data/lib/active_support/core_ext/numeric.rb +2 -0
- data/lib/active_support/core_ext/object/acts_like.rb +4 -4
- data/lib/active_support/core_ext/object/blank.rb +52 -18
- data/lib/active_support/core_ext/object/deep_dup.rb +53 -0
- data/lib/active_support/core_ext/object/duplicable.rb +12 -20
- data/lib/active_support/core_ext/object/inclusion.rb +13 -1
- data/lib/active_support/core_ext/object/instance_variables.rb +7 -12
- data/lib/active_support/core_ext/object/json.rb +205 -0
- data/lib/active_support/core_ext/object/to_param.rb +1 -55
- data/lib/active_support/core_ext/object/to_query.rb +66 -9
- data/lib/active_support/core_ext/object/try.rb +124 -33
- data/lib/active_support/core_ext/object/with_options.rb +37 -11
- data/lib/active_support/core_ext/object.rb +2 -1
- data/lib/active_support/core_ext/range/conversions.rb +17 -7
- data/lib/active_support/core_ext/range/each.rb +21 -0
- data/lib/active_support/core_ext/range/include_range.rb +20 -18
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/range.rb +1 -2
- data/lib/active_support/core_ext/securerandom.rb +23 -0
- data/lib/active_support/core_ext/string/access.rb +95 -90
- data/lib/active_support/core_ext/string/behavior.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +41 -38
- data/lib/active_support/core_ext/string/exclude.rb +6 -1
- data/lib/active_support/core_ext/string/filters.rb +70 -17
- data/lib/active_support/core_ext/string/indent.rb +43 -0
- data/lib/active_support/core_ext/string/inflections.rb +139 -59
- data/lib/active_support/core_ext/string/inquiry.rb +2 -2
- data/lib/active_support/core_ext/string/multibyte.rb +46 -65
- data/lib/active_support/core_ext/string/output_safety.rb +153 -56
- data/lib/active_support/core_ext/string/strip.rb +3 -6
- data/lib/active_support/core_ext/string/zones.rb +14 -0
- data/lib/active_support/core_ext/string.rb +2 -3
- data/lib/active_support/core_ext/struct.rb +3 -0
- data/lib/active_support/core_ext/time/calculations.rb +173 -173
- data/lib/active_support/core_ext/time/compatibility.rb +5 -0
- data/lib/active_support/core_ext/time/conversions.rb +33 -29
- data/lib/active_support/core_ext/time/marshal.rb +2 -56
- data/lib/active_support/core_ext/time/zones.rb +57 -32
- data/lib/active_support/core_ext/time.rb +5 -0
- data/lib/active_support/core_ext/uri.rb +13 -19
- data/lib/active_support/core_ext.rb +3 -2
- data/lib/active_support/dependencies/autoload.rb +47 -20
- data/lib/active_support/dependencies/interlock.rb +51 -0
- data/lib/active_support/dependencies.rb +315 -265
- data/lib/active_support/deprecation/behaviors.rb +71 -30
- data/lib/active_support/deprecation/instance_delegator.rb +24 -0
- data/lib/active_support/deprecation/method_wrappers.rb +59 -18
- data/lib/active_support/deprecation/proxy_wrappers.rb +82 -14
- data/lib/active_support/deprecation/reporting.rb +61 -14
- data/lib/active_support/deprecation.rb +38 -13
- data/lib/active_support/descendants_tracker.rb +34 -19
- data/lib/active_support/duration/iso8601_parser.rb +122 -0
- data/lib/active_support/duration/iso8601_serializer.rb +51 -0
- data/lib/active_support/duration.rb +85 -14
- data/lib/active_support/evented_file_update_checker.rb +194 -0
- data/lib/active_support/execution_wrapper.rb +117 -0
- data/lib/active_support/executor.rb +6 -0
- data/lib/active_support/file_update_checker.rb +138 -17
- data/lib/active_support/gem_version.rb +15 -0
- data/lib/active_support/gzip.rb +11 -5
- data/lib/active_support/hash_with_indifferent_access.rb +199 -49
- data/lib/active_support/i18n.rb +6 -2
- data/lib/active_support/i18n_railtie.rb +40 -21
- data/lib/active_support/inflections.rb +22 -13
- data/lib/active_support/inflector/inflections.rb +175 -144
- data/lib/active_support/inflector/methods.rb +328 -91
- data/lib/active_support/inflector/transliterate.rb +51 -37
- data/lib/active_support/json/decoding.rb +31 -22
- data/lib/active_support/json/encoding.rb +88 -248
- data/lib/active_support/key_generator.rb +71 -0
- data/lib/active_support/lazy_load_hooks.rb +27 -25
- data/lib/active_support/locale/en.yml +102 -3
- data/lib/active_support/log_subscriber/test_helper.rb +24 -21
- data/lib/active_support/log_subscriber.rb +36 -49
- data/lib/active_support/logger.rb +106 -0
- data/lib/active_support/logger_silence.rb +28 -0
- data/lib/active_support/logger_thread_safe_level.rb +31 -0
- data/lib/active_support/message_encryptor.rb +72 -36
- data/lib/active_support/message_verifier.rb +96 -24
- data/lib/active_support/multibyte/chars.rb +88 -333
- data/lib/active_support/multibyte/unicode.rb +156 -136
- data/lib/active_support/multibyte.rb +5 -28
- data/lib/active_support/notifications/fanout.rb +115 -19
- data/lib/active_support/notifications/instrumenter.rb +52 -15
- data/lib/active_support/notifications.rb +168 -33
- data/lib/active_support/number_helper/number_converter.rb +182 -0
- data/lib/active_support/number_helper/number_to_currency_converter.rb +44 -0
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +28 -0
- data/lib/active_support/number_helper/number_to_human_converter.rb +68 -0
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +62 -0
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +12 -0
- data/lib/active_support/number_helper/number_to_phone_converter.rb +58 -0
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +92 -0
- data/lib/active_support/number_helper.rb +368 -0
- data/lib/active_support/option_merger.rb +1 -1
- data/lib/active_support/ordered_hash.rb +18 -183
- data/lib/active_support/ordered_options.rb +44 -24
- data/lib/active_support/per_thread_registry.rb +58 -0
- data/lib/active_support/proxy_object.rb +13 -0
- data/lib/active_support/rails.rb +27 -0
- data/lib/active_support/railtie.rb +25 -34
- data/lib/active_support/reloader.rb +129 -0
- data/lib/active_support/rescuable.rb +98 -48
- data/lib/active_support/security_utils.rb +27 -0
- data/lib/active_support/string_inquirer.rb +14 -9
- data/lib/active_support/subscriber.rb +120 -0
- data/lib/active_support/tagged_logging.rb +78 -0
- data/lib/active_support/test_case.rb +69 -17
- data/lib/active_support/testing/assertions.rb +43 -41
- data/lib/active_support/testing/autorun.rb +12 -0
- data/lib/active_support/testing/constant_lookup.rb +50 -0
- data/lib/active_support/testing/declarative.rb +7 -21
- data/lib/active_support/testing/deprecation.rb +14 -33
- data/lib/active_support/testing/file_fixtures.rb +34 -0
- data/lib/active_support/testing/isolation.rb +53 -95
- data/lib/active_support/testing/method_call_assertions.rb +41 -0
- data/lib/active_support/testing/setup_and_teardown.rb +21 -82
- data/lib/active_support/testing/stream.rb +42 -0
- data/lib/active_support/testing/tagged_logging.rb +25 -0
- data/lib/active_support/testing/time_helpers.rb +134 -0
- data/lib/active_support/time.rb +6 -23
- data/lib/active_support/time_with_zone.rb +239 -92
- data/lib/active_support/values/time_zone.rb +236 -160
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +5 -7
- data/lib/active_support/xml_mini/jdom.rb +19 -13
- data/lib/active_support/xml_mini/libxml.rb +3 -4
- data/lib/active_support/xml_mini/libxmlsax.rb +2 -3
- data/lib/active_support/xml_mini/nokogiri.rb +3 -4
- data/lib/active_support/xml_mini/nokogirisax.rb +2 -3
- data/lib/active_support/xml_mini/rexml.rb +8 -10
- data/lib/active_support/xml_mini.rb +66 -34
- data/lib/active_support.rb +40 -23
- metadata +185 -134
- data/CHANGELOG +0 -1534
- data/lib/active_support/base64.rb +0 -42
- data/lib/active_support/basic_object.rb +0 -21
- data/lib/active_support/buffered_logger.rb +0 -137
- data/lib/active_support/cache/compressed_mem_cache_store.rb +0 -13
- data/lib/active_support/cache/synchronized_memory_store.rb +0 -11
- data/lib/active_support/core_ext/array/random_access.rb +0 -30
- data/lib/active_support/core_ext/array/uniq_by.rb +0 -16
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -44
- data/lib/active_support/core_ext/class/inheritable_attributes.rb +0 -178
- data/lib/active_support/core_ext/date/freeze.rb +0 -31
- data/lib/active_support/core_ext/date_time/zones.rb +0 -21
- 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 -11
- data/lib/active_support/core_ext/hash/diff.rb +0 -13
- data/lib/active_support/core_ext/kernel/requires.rb +0 -28
- data/lib/active_support/core_ext/logger.rb +0 -81
- data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +0 -31
- data/lib/active_support/core_ext/module/method_names.rb +0 -14
- data/lib/active_support/core_ext/module/synchronization.rb +0 -43
- data/lib/active_support/core_ext/object/to_json.rb +0 -19
- data/lib/active_support/core_ext/proc.rb +0 -14
- 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/encoding.rb +0 -11
- 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/file_watcher.rb +0 -36
- data/lib/active_support/json/variable.rb +0 -9
- data/lib/active_support/memoizable.rb +0 -105
- 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/secure_random.rb +0 -6
- data/lib/active_support/testing/mochaing.rb +0 -7
- data/lib/active_support/testing/pending.rb +0 -52
- 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 -60
@@ -1,21 +1,23 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
#
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
1
|
+
module ActiveSupport
|
2
|
+
module IncludeWithRange #:nodoc:
|
3
|
+
# Extends the default Range#include? to support range comparisons.
|
4
|
+
# (1..5).include?(1..5) # => true
|
5
|
+
# (1..5).include?(2..3) # => true
|
6
|
+
# (1..5).include?(2..6) # => false
|
7
|
+
#
|
8
|
+
# The native Range#include? behavior is untouched.
|
9
|
+
# ('a'..'f').include?('c') # => true
|
10
|
+
# (5..9).include?(11) # => false
|
11
|
+
def include?(value)
|
12
|
+
if value.is_a?(::Range)
|
13
|
+
# 1...10 includes 1..9 but it does not include 1..10.
|
14
|
+
operator = exclude_end? && !value.exclude_end? ? :< : :<=
|
15
|
+
super(value.first) && value.last.send(operator, last)
|
16
|
+
else
|
17
|
+
super
|
18
|
+
end
|
17
19
|
end
|
18
20
|
end
|
19
|
-
|
20
|
-
alias_method_chain :include?, :range
|
21
21
|
end
|
22
|
+
|
23
|
+
Range.prepend(ActiveSupport::IncludeWithRange)
|
@@ -1,5 +1,4 @@
|
|
1
|
-
require 'active_support/core_ext/range/blockless_step'
|
2
1
|
require 'active_support/core_ext/range/conversions'
|
3
2
|
require 'active_support/core_ext/range/include_range'
|
4
3
|
require 'active_support/core_ext/range/overlaps'
|
5
|
-
require 'active_support/core_ext/range/
|
4
|
+
require 'active_support/core_ext/range/each'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
module SecureRandom
|
4
|
+
BASE58_ALPHABET = ('0'..'9').to_a + ('A'..'Z').to_a + ('a'..'z').to_a - ['0', 'O', 'I', 'l']
|
5
|
+
# SecureRandom.base58 generates a random base58 string.
|
6
|
+
#
|
7
|
+
# The argument _n_ specifies the length, of the random string to be generated.
|
8
|
+
#
|
9
|
+
# If _n_ is not specified or is nil, 16 is assumed. It may be larger in the future.
|
10
|
+
#
|
11
|
+
# The result may contain alphanumeric characters except 0, O, I and l
|
12
|
+
#
|
13
|
+
# p SecureRandom.base58 # => "4kUgL2pdQMSCQtjE"
|
14
|
+
# p SecureRandom.base58(24) # => "77TMHrHJFvFDwodq8w7Ev2m7"
|
15
|
+
#
|
16
|
+
def self.base58(n = 16)
|
17
|
+
SecureRandom.random_bytes(n).unpack("C*").map do |byte|
|
18
|
+
idx = byte % 64
|
19
|
+
idx = SecureRandom.random_number(58) if idx >= 58
|
20
|
+
BASE58_ALPHABET[idx]
|
21
|
+
end.join
|
22
|
+
end
|
23
|
+
end
|
@@ -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 integer, 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 a copy of 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.dup
|
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 a copy of 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.dup
|
100
|
+
else
|
101
|
+
from(-limit)
|
97
102
|
end
|
98
103
|
end
|
99
104
|
end
|
@@ -1,54 +1,57 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
require 'date'
|
3
|
-
require 'active_support/core_ext/time/publicize_conversion_methods'
|
4
2
|
require 'active_support/core_ext/time/calculations'
|
5
3
|
|
6
4
|
class String
|
7
|
-
#
|
8
|
-
#
|
5
|
+
# Converts a string to a Time value.
|
6
|
+
# The +form+ can be either :utc or :local (default :local).
|
9
7
|
#
|
10
|
-
#
|
11
|
-
#
|
8
|
+
# The time is parsed using Time.parse method.
|
9
|
+
# If +form+ is :local, then the time is in the system timezone.
|
10
|
+
# If the date part is missing then the current date is used and if
|
11
|
+
# the time part is missing then it is assumed to be 00:00:00.
|
12
12
|
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
# represented as a single byte, 224. In UTF8 it is represented with two
|
24
|
-
# bytes, namely 195 and 160, but its Unicode codepoint is 224. If we
|
25
|
-
# call +ord+ on the UTF8 string "à" the return value will be 195. That is
|
26
|
-
# not an error, because UTF8 is unsupported, the call itself would be
|
27
|
-
# bogus.
|
28
|
-
def ord
|
29
|
-
self[0]
|
30
|
-
end unless method_defined?(:ord)
|
13
|
+
# "13-12-2012".to_time # => 2012-12-13 00:00:00 +0100
|
14
|
+
# "06:12".to_time # => 2012-12-13 06:12:00 +0100
|
15
|
+
# "2012-12-13 06:12".to_time # => 2012-12-13 06:12:00 +0100
|
16
|
+
# "2012-12-13T06:12".to_time # => 2012-12-13 06:12:00 +0100
|
17
|
+
# "2012-12-13T06:12".to_time(:utc) # => 2012-12-13 06:12:00 UTC
|
18
|
+
# "12/13/2012".to_time # => ArgumentError: argument out of range
|
19
|
+
def to_time(form = :local)
|
20
|
+
parts = Date._parse(self, false)
|
21
|
+
used_keys = %i(year mon mday hour min sec sec_fraction offset)
|
22
|
+
return if (parts.keys & used_keys).empty?
|
31
23
|
|
32
|
-
|
33
|
-
|
24
|
+
now = Time.now
|
25
|
+
time = Time.new(
|
26
|
+
parts.fetch(:year, now.year),
|
27
|
+
parts.fetch(:mon, now.month),
|
28
|
+
parts.fetch(:mday, now.day),
|
29
|
+
parts.fetch(:hour, 0),
|
30
|
+
parts.fetch(:min, 0),
|
31
|
+
parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0),
|
32
|
+
parts.fetch(:offset, form == :utc ? 0 : nil)
|
33
|
+
)
|
34
34
|
|
35
|
-
|
36
|
-
def to_time(form = :utc)
|
37
|
-
return nil if self.blank?
|
38
|
-
d = ::Date._parse(self, false).values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction).map { |arg| arg || 0 }
|
39
|
-
d[6] *= 1000000
|
40
|
-
::Time.send("#{form}_time", *d)
|
35
|
+
form == :utc ? time.utc : time.to_time
|
41
36
|
end
|
42
37
|
|
38
|
+
# Converts a string to a Date value.
|
39
|
+
#
|
40
|
+
# "1-1-2012".to_date # => Sun, 01 Jan 2012
|
41
|
+
# "01/01/2012".to_date # => Sun, 01 Jan 2012
|
42
|
+
# "2012-12-13".to_date # => Thu, 13 Dec 2012
|
43
|
+
# "12/13/2012".to_date # => ArgumentError: invalid date
|
43
44
|
def to_date
|
44
|
-
|
45
|
-
::Date.new(*::Date._parse(self, false).values_at(:year, :mon, :mday))
|
45
|
+
::Date.parse(self, false) unless blank?
|
46
46
|
end
|
47
47
|
|
48
|
+
# Converts a string to a DateTime value.
|
49
|
+
#
|
50
|
+
# "1-1-2012".to_datetime # => Sun, 01 Jan 2012 00:00:00 +0000
|
51
|
+
# "01/01/2012 23:59:59".to_datetime # => Sun, 01 Jan 2012 23:59:59 +0000
|
52
|
+
# "2012-12-13 12:50".to_datetime # => Thu, 13 Dec 2012 12:50:00 +0000
|
53
|
+
# "12/13/2012".to_datetime # => ArgumentError: invalid date
|
48
54
|
def to_datetime
|
49
|
-
|
50
|
-
d = ::Date._parse(self, false).values_at(:year, :mon, :mday, :hour, :min, :sec, :zone, :sec_fraction).map { |arg| arg || 0 }
|
51
|
-
d[5] += d.pop
|
52
|
-
::DateTime.civil(*d)
|
55
|
+
::DateTime.parse(self, false) unless blank?
|
53
56
|
end
|
54
57
|
end
|
@@ -1,5 +1,10 @@
|
|
1
1
|
class String
|
2
|
-
# The inverse of <tt>String#include?</tt>. Returns true if the string
|
2
|
+
# The inverse of <tt>String#include?</tt>. Returns true if the string
|
3
|
+
# does not include the other string.
|
4
|
+
#
|
5
|
+
# "hello".exclude? "lo" # => false
|
6
|
+
# "hello".exclude? "ol" # => true
|
7
|
+
# "hello".exclude? ?h # => false
|
3
8
|
def exclude?(string)
|
4
9
|
!include?(string)
|
5
10
|
end
|
@@ -1,11 +1,10 @@
|
|
1
|
-
require 'active_support/core_ext/string/multibyte'
|
2
|
-
|
3
1
|
class String
|
4
2
|
# Returns the string, first removing all whitespace on both ends of
|
5
3
|
# the string, and then changing remaining consecutive whitespace
|
6
4
|
# groups into one space each.
|
7
5
|
#
|
8
|
-
#
|
6
|
+
# Note that it handles both ASCII and Unicode whitespace.
|
7
|
+
#
|
9
8
|
# %{ Multi-line
|
10
9
|
# string }.squish # => "Multi-line string"
|
11
10
|
# " foo bar \n \t boo".squish # => "foo bar boo"
|
@@ -14,36 +13,90 @@ class String
|
|
14
13
|
end
|
15
14
|
|
16
15
|
# Performs a destructive squish. See String#squish.
|
16
|
+
# str = " foo bar \n \t boo"
|
17
|
+
# str.squish! # => "foo bar boo"
|
18
|
+
# str # => "foo bar boo"
|
17
19
|
def squish!
|
20
|
+
gsub!(/[[:space:]]+/, ' ')
|
18
21
|
strip!
|
19
|
-
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns a new string with all occurrences of the patterns removed.
|
26
|
+
# str = "foo bar test"
|
27
|
+
# str.remove(" test") # => "foo bar"
|
28
|
+
# str.remove(" test", /bar/) # => "foo "
|
29
|
+
# str # => "foo bar test"
|
30
|
+
def remove(*patterns)
|
31
|
+
dup.remove!(*patterns)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Alters the string by removing all occurrences of the patterns.
|
35
|
+
# str = "foo bar test"
|
36
|
+
# str.remove!(" test", /bar/) # => "foo "
|
37
|
+
# str # => "foo "
|
38
|
+
def remove!(*patterns)
|
39
|
+
patterns.each do |pattern|
|
40
|
+
gsub! pattern, ""
|
41
|
+
end
|
42
|
+
|
20
43
|
self
|
21
44
|
end
|
22
45
|
|
23
46
|
# Truncates a given +text+ after a given <tt>length</tt> if +text+ is longer than <tt>length</tt>:
|
24
47
|
#
|
25
|
-
#
|
48
|
+
# 'Once upon a time in a world far far away'.truncate(27)
|
26
49
|
# # => "Once upon a time in a wo..."
|
27
50
|
#
|
28
|
-
# Pass a <tt>:separator</tt> to truncate +text+ at a natural break:
|
51
|
+
# Pass a string or regexp <tt>:separator</tt> to truncate +text+ at a natural break:
|
29
52
|
#
|
30
|
-
#
|
53
|
+
# 'Once upon a time in a world far far away'.truncate(27, separator: ' ')
|
54
|
+
# # => "Once upon a time in a..."
|
55
|
+
#
|
56
|
+
# 'Once upon a time in a world far far away'.truncate(27, separator: /\s/)
|
31
57
|
# # => "Once upon a time in a..."
|
32
58
|
#
|
33
59
|
# The last characters will be replaced with the <tt>:omission</tt> string (defaults to "...")
|
34
|
-
# for a total length not exceeding <tt
|
60
|
+
# for a total length not exceeding <tt>length</tt>:
|
35
61
|
#
|
36
|
-
#
|
62
|
+
# 'And they found that many people were sleeping better.'.truncate(25, omission: '... (continued)')
|
37
63
|
# # => "And they f... (continued)"
|
38
|
-
def truncate(
|
39
|
-
|
40
|
-
|
64
|
+
def truncate(truncate_at, options = {})
|
65
|
+
return dup unless length > truncate_at
|
66
|
+
|
67
|
+
omission = options[:omission] || '...'
|
68
|
+
length_with_room_for_omission = truncate_at - omission.length
|
69
|
+
stop = \
|
70
|
+
if options[:separator]
|
71
|
+
rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission
|
72
|
+
else
|
73
|
+
length_with_room_for_omission
|
74
|
+
end
|
41
75
|
|
42
|
-
|
43
|
-
|
44
|
-
stop = options[:separator] ?
|
45
|
-
(chars.rindex(options[:separator].mb_chars, length_with_room_for_omission) || length_with_room_for_omission) : length_with_room_for_omission
|
76
|
+
"#{self[0, stop]}#{omission}"
|
77
|
+
end
|
46
78
|
|
47
|
-
|
79
|
+
# Truncates a given +text+ after a given number of words (<tt>words_count</tt>):
|
80
|
+
#
|
81
|
+
# 'Once upon a time in a world far far away'.truncate_words(4)
|
82
|
+
# # => "Once upon a time..."
|
83
|
+
#
|
84
|
+
# Pass a string or regexp <tt>:separator</tt> to specify a different separator of words:
|
85
|
+
#
|
86
|
+
# 'Once<br>upon<br>a<br>time<br>in<br>a<br>world'.truncate_words(5, separator: '<br>')
|
87
|
+
# # => "Once<br>upon<br>a<br>time<br>in..."
|
88
|
+
#
|
89
|
+
# The last characters will be replaced with the <tt>:omission</tt> string (defaults to "..."):
|
90
|
+
#
|
91
|
+
# 'And they found that many people were sleeping better.'.truncate_words(5, omission: '... (continued)')
|
92
|
+
# # => "And they found that many... (continued)"
|
93
|
+
def truncate_words(words_count, options = {})
|
94
|
+
sep = options[:separator] || /\s+/
|
95
|
+
sep = Regexp.escape(sep.to_s) unless Regexp === sep
|
96
|
+
if self =~ /\A((?>.+?#{sep}){#{words_count - 1}}.+?)#{sep}.*/m
|
97
|
+
$1 + (options[:omission] || '...')
|
98
|
+
else
|
99
|
+
dup
|
100
|
+
end
|
48
101
|
end
|
49
102
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class String
|
2
|
+
# Same as +indent+, except it indents the receiver in-place.
|
3
|
+
#
|
4
|
+
# Returns the indented string, or +nil+ if there was nothing to indent.
|
5
|
+
def indent!(amount, indent_string=nil, indent_empty_lines=false)
|
6
|
+
indent_string = indent_string || self[/^[ \t]/] || ' '
|
7
|
+
re = indent_empty_lines ? /^/ : /^(?!$)/
|
8
|
+
gsub!(re, indent_string * amount)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Indents the lines in the receiver:
|
12
|
+
#
|
13
|
+
# <<EOS.indent(2)
|
14
|
+
# def some_method
|
15
|
+
# some_code
|
16
|
+
# end
|
17
|
+
# EOS
|
18
|
+
# # =>
|
19
|
+
# def some_method
|
20
|
+
# some_code
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# The second argument, +indent_string+, specifies which indent string to
|
24
|
+
# use. The default is +nil+, which tells the method to make a guess by
|
25
|
+
# peeking at the first indented line, and fallback to a space if there is
|
26
|
+
# none.
|
27
|
+
#
|
28
|
+
# " foo".indent(2) # => " foo"
|
29
|
+
# "foo\n\t\tbar".indent(2) # => "\t\tfoo\n\t\t\t\tbar"
|
30
|
+
# "foo".indent(2, "\t") # => "\t\tfoo"
|
31
|
+
#
|
32
|
+
# While +indent_string+ is typically one space or tab, it may be any string.
|
33
|
+
#
|
34
|
+
# The third argument, +indent_empty_lines+, is a flag that says whether
|
35
|
+
# empty lines should be indented. Default is false.
|
36
|
+
#
|
37
|
+
# "foo\n\nbar".indent(2) # => " foo\n\n bar"
|
38
|
+
# "foo\n\nbar".indent(2, nil, true) # => " foo\n \n bar"
|
39
|
+
#
|
40
|
+
def indent(amount, indent_string=nil, indent_empty_lines=false)
|
41
|
+
dup.tap {|_| _.indent!(amount, indent_string, indent_empty_lines)}
|
42
|
+
end
|
43
|
+
end
|