mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
update AS/log_subscriber and AS/multibyte docs [ci skip]
This commit is contained in:
parent
7ef21d80a3
commit
d48163c65d
3 changed files with 76 additions and 55 deletions
|
@ -23,15 +23,15 @@ module ActiveSupport
|
|||
# end
|
||||
# end
|
||||
#
|
||||
# All you need to do is to ensure that your log subscriber is added to Rails::Subscriber,
|
||||
# as in the second line of the code above. The test helpers are responsible for setting
|
||||
# up the queue, subscriptions and turning colors in logs off.
|
||||
#
|
||||
# The messages are available in the @logger instance, which is a logger with limited
|
||||
# powers (it actually does not send anything to your output), and you can collect them
|
||||
# doing @logger.logged(level), where level is the level used in logging, like info,
|
||||
# debug, warn and so on.
|
||||
# All you need to do is to ensure that your log subscriber is added to
|
||||
# Rails::Subscriber, as in the second line of the code above. The test
|
||||
# helpers are responsible for setting up the queue, subscriptions and
|
||||
# turning colors in logs off.
|
||||
#
|
||||
# The messages are available in the @logger instance, which is a logger with
|
||||
# limited powers (it actually does not send anything to your output), and
|
||||
# you can collect them doing @logger.logged(level), where level is the level
|
||||
# used in logging, like info, debug, warn and so on.
|
||||
module TestHelper
|
||||
def setup
|
||||
@logger = MockLogger.new
|
||||
|
@ -91,12 +91,11 @@ module ActiveSupport
|
|||
@notifier.wait
|
||||
end
|
||||
|
||||
# Overwrite if you use another logger in your log subscriber:
|
||||
# Overwrite if you use another logger in your log subscriber.
|
||||
#
|
||||
# def logger
|
||||
# ActiveRecord::Base.logger = @logger
|
||||
# end
|
||||
#
|
||||
def set_logger(logger)
|
||||
ActiveSupport::LogSubscriber.logger = logger
|
||||
end
|
||||
|
|
|
@ -6,22 +6,27 @@ require 'active_support/core_ext/module/delegation'
|
|||
|
||||
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 Chars object accepts a string upon initialization and proxies String methods in an
|
||||
# encoding safe manner. All the normal String methods are also implemented on the proxy.
|
||||
# Chars enables you to work transparently with UTF-8 encoding in the Ruby
|
||||
# String class without having extensive knowledge about the encoding. A
|
||||
# Chars object accepts a string upon initialization and proxies String
|
||||
# methods in an encoding safe manner. All the normal String methods are also
|
||||
# implemented on the proxy.
|
||||
#
|
||||
# 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.
|
||||
# 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 # => "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.
|
||||
# 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.
|
||||
#
|
||||
# bad.explicit_checking_method "T".mb_chars.downcase.to_s
|
||||
# bad.explicit_checking_method 'T'.mb_chars.downcase.to_s
|
||||
#
|
||||
# The default Chars implementation assumes that the encoding of the string is UTF-8, if you want to handle different
|
||||
# encodings you can write your own multibyte string handler and configure it through
|
||||
# The default Chars implementation assumes that the encoding of the string
|
||||
# is UTF-8, if you want to handle different encodings you can write your own
|
||||
# multibyte string handler and configure it through
|
||||
# ActiveSupport::Multibyte.proxy_class.
|
||||
#
|
||||
# class CharsForUTF32
|
||||
|
@ -60,27 +65,30 @@ module ActiveSupport #:nodoc:
|
|||
end
|
||||
end
|
||||
|
||||
# Returns +true+ if _obj_ responds to the given method. Private methods are included in the search
|
||||
# only if the optional second parameter evaluates to +true+.
|
||||
# Returns +true+ if _obj_ responds to the given method. Private methods
|
||||
# are included in the search only if the optional second parameter
|
||||
# evaluates to +true+.
|
||||
def respond_to_missing?(method, include_private)
|
||||
@wrapped_string.respond_to?(method, include_private)
|
||||
end
|
||||
|
||||
# Returns +true+ when the proxy class can handle the string. Returns +false+ otherwise.
|
||||
# Returns +true+ when the proxy class can handle the string. Returns
|
||||
# +false+ otherwise.
|
||||
def self.consumes?(string)
|
||||
string.encoding == Encoding::UTF_8
|
||||
end
|
||||
|
||||
# Works just like <tt>String#split</tt>, with the exception that the items in the resulting list are Chars
|
||||
# instances instead of String. This makes chaining methods easier.
|
||||
# Works just like <tt>String#split</tt>, with the exception that the items
|
||||
# in the resulting list are Chars instances instead of String. This makes
|
||||
# chaining methods easier.
|
||||
#
|
||||
# 'Café périferôl'.mb_chars.split(/é/).map { |part| part.upcase.to_s } # => ["CAF", " P", "RIFERÔL"]
|
||||
def split(*args)
|
||||
@wrapped_string.split(*args).map { |i| self.class.new(i) }
|
||||
end
|
||||
|
||||
# Works like like <tt>String#slice!</tt>, but returns an instance of Chars, or nil if the string was not
|
||||
# modified.
|
||||
# Works like like <tt>String#slice!</tt>, but returns an instance of
|
||||
# Chars, or nil if the string was not modified.
|
||||
def slice!(*args)
|
||||
chars(@wrapped_string.slice!(*args))
|
||||
end
|
||||
|
@ -92,8 +100,9 @@ module ActiveSupport #:nodoc:
|
|||
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.
|
||||
# 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.
|
||||
#
|
||||
# 'こんにちは'.mb_chars.limit(7).to_s # => "こん"
|
||||
def limit(limit)
|
||||
|
@ -137,8 +146,9 @@ module ActiveSupport #:nodoc:
|
|||
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 and validations.
|
||||
# Returns the KC normalization of the string by default. NFKC is
|
||||
# considered the best normalization form for passing strings to databases
|
||||
# and validations.
|
||||
#
|
||||
# * <tt>form</tt> - The form you want to normalize in. Should be one of the following:
|
||||
# <tt>:c</tt>, <tt>:kc</tt>, <tt>:d</tt>, or <tt>:kd</tt>. Default is
|
||||
|
@ -171,9 +181,11 @@ module ActiveSupport #:nodoc:
|
|||
Unicode.unpack_graphemes(@wrapped_string).length
|
||||
end
|
||||
|
||||
# Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent resulting in a valid UTF-8 string.
|
||||
# Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent
|
||||
# resulting in a valid UTF-8 string.
|
||||
#
|
||||
# Passing +true+ will forcibly tidy all bytes, assuming that the string's encoding is entirely CP1252 or ISO-8859-1.
|
||||
# Passing +true+ will forcibly tidy all bytes, assuming that the string's
|
||||
# encoding is entirely CP1252 or ISO-8859-1.
|
||||
def tidy_bytes(force = false)
|
||||
chars(Unicode.tidy_bytes(@wrapped_string, force))
|
||||
end
|
||||
|
|
|
@ -5,15 +5,17 @@ module ActiveSupport
|
|||
|
||||
extend self
|
||||
|
||||
# A list of all available normalization forms. See http://www.unicode.org/reports/tr15/tr15-29.html for more
|
||||
# A list of all available normalization forms.
|
||||
# See http://www.unicode.org/reports/tr15/tr15-29.html for more
|
||||
# information about normalization.
|
||||
NORMALIZATION_FORMS = [:c, :kc, :d, :kd]
|
||||
|
||||
# The Unicode version that is supported by the implementation
|
||||
UNICODE_VERSION = '6.1.0'
|
||||
|
||||
# The default normalization used for operations that require normalization. It can be set to any of the
|
||||
# normalizations in NORMALIZATION_FORMS.
|
||||
# The default normalization used for operations that require
|
||||
# normalization. It can be set to any of the normalizations
|
||||
# in NORMALIZATION_FORMS.
|
||||
#
|
||||
# ActiveSupport::Multibyte::Unicode.default_normalization_form = :c
|
||||
attr_accessor :default_normalization_form
|
||||
|
@ -49,19 +51,22 @@ module ActiveSupport
|
|||
0x3000, # White_Space # Zs IDEOGRAPHIC SPACE
|
||||
].flatten.freeze
|
||||
|
||||
# BOM (byte order mark) can also be seen as whitespace, it's a non-rendering character used to distinguish
|
||||
# between little and big endian. This is not an issue in utf-8, so it must be ignored.
|
||||
# BOM (byte order mark) can also be seen as whitespace, it's a
|
||||
# non-rendering character used to distinguish between little and big
|
||||
# endian. This is not an issue in utf-8, so it must be ignored.
|
||||
LEADERS_AND_TRAILERS = WHITESPACE + [65279] # ZERO-WIDTH NO-BREAK SPACE aka BOM
|
||||
|
||||
# Returns a regular expression pattern that matches the passed Unicode codepoints
|
||||
# Returns a regular expression pattern that matches the passed Unicode
|
||||
# codepoints.
|
||||
def self.codepoints_to_pattern(array_of_codepoints) #:nodoc:
|
||||
array_of_codepoints.collect{ |e| [e].pack 'U*' }.join('|')
|
||||
end
|
||||
TRAILERS_PAT = /(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+\Z/u
|
||||
LEADERS_PAT = /\A(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+/u
|
||||
|
||||
# Detect whether the codepoint is in a certain character class. Returns +true+ when it's in the specified
|
||||
# character class and +false+ otherwise. Valid character classes are: <tt>:cr</tt>, <tt>:lf</tt>, <tt>:l</tt>,
|
||||
# Detect whether the codepoint is in a certain character class. Returns
|
||||
# +true+ when it's in the specified character class and +false+ otherwise.
|
||||
# Valid character classes are: <tt>:cr</tt>, <tt>:lf</tt>, <tt>:l</tt>,
|
||||
# <tt>:v</tt>, <tt>:lv</tt>, <tt>:lvt</tt> and <tt>:t</tt>.
|
||||
#
|
||||
# Primarily used by the grapheme cluster support.
|
||||
|
@ -69,7 +74,8 @@ module ActiveSupport
|
|||
classes.detect { |c| database.boundary[c] === codepoint } ? true : false
|
||||
end
|
||||
|
||||
# Unpack the string at grapheme boundaries. Returns a list of character lists.
|
||||
# Unpack the string at grapheme boundaries. Returns a list of character
|
||||
# lists.
|
||||
#
|
||||
# Unicode.unpack_graphemes('क्षि') # => [[2325, 2381], [2359], [2367]]
|
||||
# Unicode.unpack_graphemes('Café') # => [[67], [97], [102], [233]]
|
||||
|
@ -206,9 +212,11 @@ module ActiveSupport
|
|||
codepoints
|
||||
end
|
||||
|
||||
# Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent resulting in a valid UTF-8 string.
|
||||
# Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent
|
||||
# resulting in a valid UTF-8 string.
|
||||
#
|
||||
# Passing +true+ will forcibly tidy all bytes, assuming that the string's encoding is entirely CP1252 or ISO-8859-1.
|
||||
# Passing +true+ will forcibly tidy all bytes, assuming that the string's
|
||||
# encoding is entirely CP1252 or ISO-8859-1.
|
||||
def tidy_bytes(string, force = false)
|
||||
if force
|
||||
return string.unpack("C*").map do |b|
|
||||
|
@ -257,13 +265,14 @@ module ActiveSupport
|
|||
bytes.empty? ? "" : bytes.flatten.compact.pack("C*").unpack("U*").pack("U*")
|
||||
end
|
||||
|
||||
# Returns the KC normalization of the string by default. NFKC is considered the best normalization form for
|
||||
# passing strings to databases and validations.
|
||||
# Returns the KC normalization of the string by default. NFKC is
|
||||
# considered the best normalization form for passing strings to databases
|
||||
# and validations.
|
||||
#
|
||||
# * <tt>string</tt> - The string to perform normalization on.
|
||||
# * <tt>form</tt> - The form you want to normalize in. Should be one of the following:
|
||||
# <tt>:c</tt>, <tt>:kc</tt>, <tt>:d</tt>, or <tt>:kd</tt>. Default is
|
||||
# ActiveSupport::Multibyte.default_normalization_form
|
||||
# * <tt>form</tt> - The form you want to normalize in. Should be one of
|
||||
# the following: <tt>:c</tt>, <tt>:kc</tt>, <tt>:d</tt>, or <tt>:kd</tt>.
|
||||
# Default is ActiveSupport::Multibyte.default_normalization_form.
|
||||
def normalize(string, form=nil)
|
||||
form ||= @default_normalization_form
|
||||
# See http://www.unicode.org/reports/tr15, Table 1
|
||||
|
@ -294,7 +303,7 @@ module ActiveSupport
|
|||
apply_mapping string, :swapcase_mapping
|
||||
end
|
||||
|
||||
# Holds data about a codepoint in the Unicode database
|
||||
# Holds data about a codepoint in the Unicode database.
|
||||
class Codepoint
|
||||
attr_accessor :code, :combining_class, :decomp_type, :decomp_mapping, :uppercase_mapping, :lowercase_mapping
|
||||
|
||||
|
@ -303,7 +312,7 @@ module ActiveSupport
|
|||
end
|
||||
end
|
||||
|
||||
# Holds static data from the Unicode database
|
||||
# Holds static data from the Unicode database.
|
||||
class UnicodeDatabase
|
||||
ATTRIBUTES = :codepoints, :composition_exclusion, :composition_map, :boundary, :cp1252
|
||||
|
||||
|
@ -327,7 +336,8 @@ module ActiveSupport
|
|||
EOS
|
||||
end
|
||||
|
||||
# Loads the Unicode database and returns all the internal objects of UnicodeDatabase.
|
||||
# Loads the Unicode database and returns all the internal objects of
|
||||
# UnicodeDatabase.
|
||||
def load
|
||||
begin
|
||||
@codepoints, @composition_exclusion, @composition_map, @boundary, @cp1252 = File.open(self.class.filename, 'rb') { |f| Marshal.load f.read }
|
||||
|
@ -350,12 +360,12 @@ module ActiveSupport
|
|||
end
|
||||
end
|
||||
|
||||
# Returns the directory in which the data files are stored
|
||||
# Returns the directory in which the data files are stored.
|
||||
def self.dirname
|
||||
File.dirname(__FILE__) + '/../values/'
|
||||
end
|
||||
|
||||
# Returns the filename for the data file for this version
|
||||
# Returns the filename for the data file for this version.
|
||||
def self.filename
|
||||
File.expand_path File.join(dirname, "unicode_tables.dat")
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue