From be196f3f7ec86e072d455cdca6acae1fd8782066 Mon Sep 17 00:00:00 2001 From: Marcel Molina Date: Tue, 31 Jul 2007 04:59:10 +0000 Subject: Add support for []= on ActiveSupport::Multibyte::Chars. Closes #9142. [ewan, manfred] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7257 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- .../multibyte/handlers/utf8_handler.rb | 38 ++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/multibyte/handlers/utf8_handler.rb b/activesupport/lib/active_support/multibyte/handlers/utf8_handler.rb index 009950d33e..02fc7b3e2b 100644 --- a/activesupport/lib/active_support/multibyte/handlers/utf8_handler.rb +++ b/activesupport/lib/active_support/multibyte/handlers/utf8_handler.rb @@ -140,6 +140,44 @@ module ActiveSupport::Multibyte::Handlers #:nodoc: bidx ? (u_unpack(str.slice(0...bidx)).size) : nil end + # Works just like the indexed replace method on string, except instead of byte offsets you specify + # character offsets. + # + # Example: + # + # s = "Müller" + # s.chars[2] = "e" # Replace character with offset 2 + # s + # #=> "Müeler" + # + # s = "Müller" + # s.chars[1, 2] = "ö" # Replace 2 characters at character offset 1 + # s + # #=> "Möler" + def []=(str, *args) + replace_by = args.pop + # Indexed replace with regular expressions already works + return str[*args] = replace_by if args.first.is_a?(Regexp) + result = u_unpack(str) + if args[0].is_a?(Fixnum) + raise IndexError, "index #{args[0]} out of string" if args[0] >= result.length + min = args[0] + max = args[1].nil? ? min : (min + args[1] - 1) + range = Range.new(min, max) + replace_by = [replace_by].pack('U') if replace_by.is_a?(Fixnum) + elsif args.first.is_a?(Range) + raise RangeError, "#{args[0]} out of range" if args[0].min >= result.length + range = args[0] + else + needle = args[0].to_s + min = index(str, needle) + max = min + length(needle) - 1 + range = Range.new(min, max) + end + result[range] = u_unpack(replace_by) + str.replace(result.pack('U*')) + end + # Does Unicode-aware rstrip def rstrip(str) str.gsub(UNICODE_TRAILERS_PAT, '') -- cgit v1.2.3