Class: ActiveSupport::Multibyte::Chars
- Inherits:
-
Object
- Object
- ActiveSupport::Multibyte::Chars
- Includes:
- Comparable
- Defined in:
- lib/unicodechars/multibyte/chars.rb
Overview
Chars enables you to work transparently with multibyte encodings 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 chars
method. Methods which would normally return a String object now return a Chars object so methods can be chained.
"The Perfect String ".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.
bad.explicit_checking_method "T".chars.downcase.to_s
The actual operations on the string are delegated to handlers. Theoretically handlers can be implemented for any encoding, but the default handler handles UTF-8. This handler is set during initialization, if you want to use you own handler, you can set it on the Chars class. Look at the UTF8Handler source for an example how to implement your own handler. If you your own handler to work on anything but UTF-8 you probably also want to override Chars#handler.
ActiveSupport::Multibyte::Chars.handler = MyHandler
Note that a few methods are defined on Chars instead of the handler because they are defined on Object or Kernel and method_missing can’t catch them.
Instance Attribute Summary collapse
-
#string ⇒ Object
(also: #to_s)
readonly
The contained string.
Class Method Summary collapse
-
.handler=(klass) ⇒ Object
Set the handler class for the Char objects.
Instance Method Summary collapse
-
#<=>(other) ⇒ Object
Returns -1, 0 or +1 depending on whether the Chars object is to be sorted before, equal or after the object on the right side of the operation.
-
#=~(other) ⇒ Object
Like String.=~ only it returns the character offset (in codepoints) instead of the byte offset.
-
#[](num) ⇒ Object
Fix [] for single numbers.
- #collect(&block) ⇒ Object (also: #map)
- #each(&block) ⇒ Object
-
#gsub(*a, &b) ⇒ Object
Gsub works exactly the same as gsub on a normal string.
-
#handler ⇒ Object
Returns the proper handler for the contained string depending on $KCODE and the encoding of the string.
-
#initialize(str) ⇒ Chars
constructor
Create a new Chars instance.
- #inject(&block) ⇒ Object
-
#inspect ⇒ Object
Makes unicode string look like a string in the console.
- #is_a?(type) ⇒ Boolean
-
#method_missing(m, *a, &b) ⇒ Object
Try to forward all undefined methods to the handler, when a method is not defined on the handler, send it to the contained string.
-
#split(*args) ⇒ Object
Works just like String#split, with the exception that the items in the resulting list are Chars instances instead of String.
- #to_a ⇒ Object
-
#to_str ⇒ Object
The magic method to make String and Chars comparable.
Constructor Details
#initialize(str) ⇒ Chars
Create a new Chars instance.
67 68 69 |
# File 'lib/unicodechars/multibyte/chars.rb', line 67 def initialize(str) @string = (str.string rescue str) end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(m, *a, &b) ⇒ Object
Try to forward all undefined methods to the handler, when a method is not defined on the handler, send it to the contained string. Method_missing is also responsible for making the bang! methods destructive.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/unicodechars/multibyte/chars.rb', line 110 def method_missing(m, *a, &b) begin # Simulate methods with a ! at the end because we can't touch the enclosed string from the handlers. if m.to_s =~ /^(.*)\!$/ result = handler.send($1, @string, *a, &b) if result == @string result = nil else @string.replace result end else result = handler.send(m, @string, *a, &b) end rescue NoMethodError result = @string.send(m, *a, &b) rescue Handlers::EncodingError @string.replace handler.tidy_bytes(@string) retry end if result.kind_of?(String) result.chars else result end end |
Instance Attribute Details
#string ⇒ Object (readonly) Also known as: to_s
The contained string
32 33 34 |
# File 'lib/unicodechars/multibyte/chars.rb', line 32 def string @string end |
Class Method Details
.handler=(klass) ⇒ Object
Set the handler class for the Char objects.
138 139 140 |
# File 'lib/unicodechars/multibyte/chars.rb', line 138 def self.handler=(klass) @@handler = klass end |
Instance Method Details
#<=>(other) ⇒ Object
Returns -1, 0 or +1 depending on whether the Chars object is to be sorted before, equal or after the object on the right side of the operation. It accepts any object that implements to_s
. See String.<=> for more details.
92 |
# File 'lib/unicodechars/multibyte/chars.rb', line 92 def <=>(other); @string <=> other.to_s; end |
#=~(other) ⇒ Object
Like String.=~ only it returns the character offset (in codepoints) instead of the byte offset.
104 105 106 |
# File 'lib/unicodechars/multibyte/chars.rb', line 104 def =~(other) handler.translate_offset(@string, @string =~ other) end |
#[](num) ⇒ Object
Fix [] for single numbers
58 59 60 61 62 63 64 |
# File 'lib/unicodechars/multibyte/chars.rb', line 58 def [](num) if num.is_a?(Fixnum) self[num..num] else super end end |
#collect(&block) ⇒ Object Also known as: map
79 80 81 |
# File 'lib/unicodechars/multibyte/chars.rb', line 79 def collect &block split(//).collect(&block) end |
#each(&block) ⇒ Object
71 72 73 |
# File 'lib/unicodechars/multibyte/chars.rb', line 71 def each &block split(//).each(&block) end |
#gsub(*a, &b) ⇒ Object
Gsub works exactly the same as gsub on a normal string.
101 |
# File 'lib/unicodechars/multibyte/chars.rb', line 101 def gsub(*a, &b); @string.gsub(*a, &b).chars; end |
#handler ⇒ Object
Returns the proper handler for the contained string depending on $KCODE and the encoding of the string. This method is used internally to always redirect messages to the proper classes depending on the context.
144 145 146 147 148 149 150 |
# File 'lib/unicodechars/multibyte/chars.rb', line 144 def handler if utf8_pragma? @@handler else ActiveSupport::Multibyte::Handlers::PassthruHandler end end |
#inject(&block) ⇒ Object
75 76 77 |
# File 'lib/unicodechars/multibyte/chars.rb', line 75 def inject &block split(//).inject(&block) end |
#inspect ⇒ Object
Makes unicode string look like a string in the console
45 46 47 |
# File 'lib/unicodechars/multibyte/chars.rb', line 45 def inspect @string.inspect end |
#is_a?(type) ⇒ Boolean
49 50 51 52 53 54 55 |
# File 'lib/unicodechars/multibyte/chars.rb', line 49 def is_a?(type) if type == String true else super end end |
#split(*args) ⇒ Object
Works just like String#split, with the exception that the items in the resulting list are Chars instances instead of String. This makes chaining methods easier.
96 97 98 |
# File 'lib/unicodechars/multibyte/chars.rb', line 96 def split(*args) @string.split(*args).map { |i| i.chars } end |
#to_a ⇒ Object
85 86 87 |
# File 'lib/unicodechars/multibyte/chars.rb', line 85 def to_a split(//) end |
#to_str ⇒ Object
The magic method to make String and Chars comparable
38 39 40 41 42 |
# File 'lib/unicodechars/multibyte/chars.rb', line 38 def to_str # Using any other ways of overriding the String itself will lead you all the way from infinite loops to # core dumps. Don't go there. @string end |