Permalink
Browse files

Fixed String#[]= for more arguments. Fixes #1985.

  • Loading branch information...
1 parent f8ece08 commit 9019747aa181b91cb6c58ea532ddbf1dc6711226 @brixen brixen committed Nov 25, 2012
Showing with 61 additions and 51 deletions.
  1. +3 −3 kernel/common/string.rb
  2. +58 −48 kernel/common/string19.rb
View
@@ -1082,9 +1082,9 @@ def subpattern_set(pattern, capture, replacement)
capture += match.size
end
- start = match.begin(capture)
- length = match.end(capture) - start
- splice! start, length, replacement
+ bi = byteindex match.begin(capture)
+ bs = byteindex(match.end(capture)) - bi
+ splice! bi, bs, replacement
end
def splice!(start, count, replacement)
View
@@ -913,81 +913,91 @@ def match(pattern, pos=0)
end
end
- def []=(index, replacement, three=undefined)
- unless three.equal?(undefined)
- if index.kind_of? Regexp
- subpattern_set index,
- Rubinius::Type.coerce_to(replacement, Integer, :to_int),
- three
- else
- start = Rubinius::Type.coerce_to(index, Integer, :to_int)
- fin = Rubinius::Type.coerce_to(replacement, Integer, :to_int)
-
- splice! start, fin, three
- end
-
- return three
+ def []=(index, count_or_replacement, replacement=undefined)
+ if replacement.equal? undefined
+ replacement = count_or_replacement
+ count = nil
+ else
+ count = count_or_replacement
end
case index
when Fixnum
# Handle this first because it's the most common.
# This is duplicated from the else branch, but don't dry it up.
- if index < 0
- index += @num_bytes
- if index < 0 or index >= @num_bytes
- raise IndexError, "index #{index} out of string"
- end
- else
- raise IndexError, "index #{index} out of string" if index > @num_bytes
+ index += size if index < 0
+
+ if index < 0 or index > size
+ raise IndexError, "index #{index} out of string"
+ end
+
+ unless bi = byteindex(index)
+ raise IndexError, "unable to find character at: #{index}"
end
- if replacement.kind_of?(Fixnum)
- modify!
- @data[index] = replacement
+ if count
+ count = Rubinius::Type.coerce_to count, Fixnum, :to_int
+
+ if count < 0
+ raise IndexError, "count is negative"
+ end
+
+ total = index + count
+ if total >= size
+ bs = bytesize - bi
+ else
+ bs = byteindex(total) - bi
+ end
else
- splice! index, 1, replacement
+ bs = index == size ? 0 : byteindex(index + 1) - bi
end
- when Regexp
- subpattern_set index, 0, replacement
+
+ splice! bi, bs, replacement
when String
+ # TODO: fix String#index
unless start = self.index(index)
raise IndexError, "string not matched"
end
splice! start, index.bytesize, replacement
when Range
- start = Rubinius::Type.coerce_to(index.first, Integer, :to_int)
- length = Rubinius::Type.coerce_to(index.last, Integer, :to_int)
+ start = Rubinius::Type.coerce_to index.first, Fixnum, :to_int
- start += @num_bytes if start < 0
+ start += size if start < 0
- return nil if start < 0 || start > @num_bytes
+ if start < 0 or start > size
+ raise RangeError, "#{index.first} is out of range"
+ end
- length = @num_bytes if length > @num_bytes
- length += @num_bytes if length < 0
- length += 1 unless index.exclude_end?
+ unless bi = byteindex(start)
+ raise IndexError, "unable to find character at: #{start}"
+ end
- length = length - start
- length = 0 if length < 0
+ stop = Rubinius::Type.coerce_to index.last, Fixnum, :to_int
+ stop -= 1 if index.exclude_end?
+ stop += size if stop < 0
- splice! start, length, replacement
- else
- index = Rubinius::Type.coerce_to(index, Integer, :to_int)
- raise IndexError, "index #{index} out of string" if @num_bytes <= index
-
- if index < 0
- raise IndexError, "index #{index} out of string" if -index > @num_bytes
- index += @num_bytes
+ if stop < start
+ bs = 0
+ elsif stop >= size
+ bs = bytesize - bi
+ else
+ bs = byteindex(stop + 1) - bi
end
- if replacement.kind_of?(Fixnum)
- modify!
- @data[index] = replacement
+ splice! bi, bs, replacement
+ when Regexp
+ subpattern_set index, count || 0, replacement
+ else
+ index = Rubinius::Type.coerce_to index, Fixnum, :to_int
+
+ if count
+ self[index, count] = replacement
else
- splice! index, 1, replacement
+ self[index] = replacement
end
end
+
return replacement
end
end

1 comment on commit 9019747

Owner

brixen commented on 9019747 Nov 26, 2012

@robgleeson lol, more on the way! :)

Please sign in to comment.