lib/active_support/multibyte/chars.rb in activesupport-5.0.7.2 vs lib/active_support/multibyte/chars.rb in activesupport-5.1.0.beta1

- old
+ new

@@ -1,9 +1,10 @@ -require 'active_support/json' -require 'active_support/core_ext/string/access' -require 'active_support/core_ext/string/behavior' -require 'active_support/core_ext/module/delegation' +require "active_support/json" +require "active_support/core_ext/string/access" +require "active_support/core_ext/string/behavior" +require "active_support/core_ext/module/delegation" +require "active_support/core_ext/regexp" module ActiveSupport #:nodoc: module Multibyte #:nodoc: # Chars enables you to work transparently with UTF-8 encoding in the Ruby # String class without having extensive knowledge about the encoding. A @@ -13,11 +14,12 @@ # # String methods are proxied through the Chars object, and can be accessed # through the +mb_chars+ method. Methods which would normally return a # String object now return a Chars object so methods can be chained. # - # 'The Perfect String '.mb_chars.downcase.strip.normalize # => "the perfect string" + # 'The Perfect String '.mb_chars.downcase.strip.normalize + # # => #<ActiveSupport::Multibyte::Chars:0x007fdc434ccc10 @wrapped_string="the perfect string"> # # Chars objects are perfectly interchangeable with String objects as long as # no explicit class checks are made. If certain methods do explicitly check # the class, call +to_s+ before you pass chars objects to them. # @@ -43,22 +45,22 @@ include Comparable attr_reader :wrapped_string alias to_s wrapped_string alias to_str wrapped_string - delegate :<=>, :=~, :acts_like_string?, :to => :wrapped_string + delegate :<=>, :=~, :acts_like_string?, to: :wrapped_string # Creates a new Chars instance by wrapping _string_. def initialize(string) @wrapped_string = string @wrapped_string.force_encoding(Encoding::UTF_8) unless @wrapped_string.frozen? end # Forward all undefined methods to the wrapped string. def method_missing(method, *args, &block) result = @wrapped_string.__send__(method, *args, &block) - if method.to_s =~ /!$/ + if /!$/.match?(method) self if result else result.kind_of?(String) ? chars(result) : result end end @@ -84,11 +86,11 @@ def split(*args) @wrapped_string.split(*args).map { |i| self.class.new(i) } end # Works like <tt>String#slice!</tt>, but returns an instance of - # Chars, or nil if the string was not modified. The string will not be + # Chars, or +nil+ if the string was not modified. The string will not be # modified if the range given is out of bounds # # string = 'Welcome' # string.mb_chars.slice!(3) # => #<ActiveSupport::Multibyte::Chars:0x000000038109b8 @wrapped_string="c"> # string # => 'Welome' @@ -103,11 +105,11 @@ # Reverses all characters in the string. # # 'Café'.mb_chars.reverse.to_s # => 'éfaC' def reverse - chars(Unicode.unpack_graphemes(@wrapped_string).reverse.flatten.pack('U*')) + chars(Unicode.unpack_graphemes(@wrapped_string).reverse.flatten.pack("U*")) end # Limits the byte size of the string to a number of bytes without breaking # characters. Usable when the storage for a string is limited for some # reason. @@ -131,28 +133,28 @@ chars Unicode.downcase(@wrapped_string) end # Converts characters in the string to the opposite case. # - # 'El Cañón".mb_chars.swapcase.to_s # => "eL cAÑÓN" + # 'El Cañón'.mb_chars.swapcase.to_s # => "eL cAÑÓN" def swapcase chars Unicode.swapcase(@wrapped_string) end # Converts the first character to uppercase and the remainder to lowercase. # # 'über'.mb_chars.capitalize.to_s # => "Über" def capitalize - (slice(0) || chars('')).upcase + (slice(1..-1) || chars('')).downcase + (slice(0) || chars("")).upcase + (slice(1..-1) || chars("")).downcase end # Capitalizes the first letter of every word, when possible. # - # "ÉL QUE SE ENTERÓ".mb_chars.titleize # => "Él Que Se Enteró" - # "日本語".mb_chars.titleize # => "日本語" + # "ÉL QUE SE ENTERÓ".mb_chars.titleize.to_s # => "Él Que Se Enteró" + # "日本語".mb_chars.titleize.to_s # => "日本語" def titleize - chars(downcase.to_s.gsub(/\b('?\S)/u) { Unicode.upcase($1)}) + chars(downcase.to_s.gsub(/\b('?\S)/u) { Unicode.upcase($1) }) end alias_method :titlecase, :titleize # Returns the KC normalization of the string by default. NFKC is # considered the best normalization form for passing strings to databases @@ -168,19 +170,19 @@ # Performs canonical decomposition on all the characters. # # 'é'.length # => 2 # 'é'.mb_chars.decompose.to_s.length # => 3 def decompose - chars(Unicode.decompose(:canonical, @wrapped_string.codepoints.to_a).pack('U*')) + chars(Unicode.decompose(:canonical, @wrapped_string.codepoints.to_a).pack("U*")) end # Performs composition on all the characters. # # 'é'.length # => 3 # 'é'.mb_chars.compose.to_s.length # => 2 def compose - chars(Unicode.compose(@wrapped_string.codepoints.to_a).pack('U*')) + chars(Unicode.compose(@wrapped_string.codepoints.to_a).pack("U*")) end # Returns the number of grapheme clusters in the string. # # 'क्षि'.mb_chars.length # => 4 @@ -207,24 +209,24 @@ @wrapped_string = send(method, *args).to_s self end end - protected + private - def translate_offset(byte_offset) #:nodoc: + def translate_offset(byte_offset) return nil if byte_offset.nil? - return 0 if @wrapped_string == '' + return 0 if @wrapped_string == "" begin - @wrapped_string.byteslice(0...byte_offset).unpack('U*').length + @wrapped_string.byteslice(0...byte_offset).unpack("U*").length rescue ArgumentError byte_offset -= 1 retry end end - def chars(string) #:nodoc: + def chars(string) self.class.new(string) end end end end