class String
include Comparable
def each_line(rs = "\n", &block)
return to_enum(:each_line, rs, &block) unless block
return block.call(self) if rs.nil?
rs.__to_str
offset = 0
rs_len = rs.length
this = dup
while pos = this.index(rs, offset)
block.call(this[offset, pos + rs_len - offset])
offset = pos + rs_len
end
block.call(this[offset, this.size - offset]) if this.size > offset
self
end
def __sub_replace(pre, m, post)
s = ""
i = 0
while j = index("\\", i)
break if j == length-1
t = case self[j+1]
when "\\"
"\\"
when "`"
pre
when "&", "0"
m
when "'"
post
when "1", "2", "3", "4", "5", "6", "7", "8", "9"
""
else
self[j, 2]
end
s += self[i, j-i] + t
i = j + 2
end
s + self[i, length-i]
end
def gsub(*args, &block)
return to_enum(:gsub, *args) if args.length == 1 && !block
raise ArgumentError, "wrong number of arguments" unless (1..2).include?(args.length)
pattern, replace = *args
plen = pattern.length
if args.length == 2 && block
block = nil
end
if !replace.nil? || !block
replace.__to_str
end
offset = 0
result = []
while found = index(pattern, offset)
result << self[offset, found - offset]
offset = found + plen
result << if block
block.call(pattern).to_s
else
replace.__sub_replace(self[0, found], pattern, self[offset..-1] || "")
end
if plen == 0
result << self[offset, 1]
offset += 1
end
end
result << self[offset..-1] if offset < length
result.join
end
def gsub!(*args, &block)
raise FrozenError, "can't modify frozen String" if frozen?
return to_enum(:gsub!, *args) if args.length == 1 && !block
str = self.gsub(*args, &block)
return nil unless self.index(args[0])
self.replace(str)
end
def scan(reg, &block)
unless Object.const_defined?(:Regexp)
raise NotImplementedError, "scan not available (yet)"
end
end
def sub(*args, &block)
unless (1..2).include?(args.length)
raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 2)"
end
pattern, replace = *args
pattern.__to_str
if args.length == 2 && block
block = nil
end
unless block
replace.__to_str
end
result = []
this = dup
found = index(pattern)
return this unless found
result << this[0, found]
offset = found + pattern.length
result << if block
block.call(pattern).to_s
else
replace.__sub_replace(this[0, found], pattern, this[offset..-1] || "")
end
result << this[offset..-1] if offset < length
result.join
end
def sub!(*args, &block)
raise FrozenError, "can't modify frozen String" if frozen?
str = self.sub(*args, &block)
return nil unless self.index(args[0])
self.replace(str)
end
def each_char(&block)
pos = 0
while pos < self.size
block.call(self[pos])
pos += 1
end
self
end
def each_byte(&block)
bytes = self.bytes
pos = 0
while pos < bytes.size
block.call(bytes[pos])
pos += 1
end
self
end
def []=(*args)
anum = args.size
if anum == 2
pos, value = args
case pos
when String
posnum = self.index(pos)
if posnum
b = self[0, posnum.to_i]
a = self[(posnum + pos.length)..-1]
self.replace([b, value, a].join(''))
else
raise IndexError, "string not matched"
end
when Range
head = pos.begin
tail = pos.end
tail += self.length if tail < 0
unless pos.exclude_end?
tail += 1
end
return self[head, tail-head]=value
else
pos += self.length if pos < 0
if pos < 0 || pos > self.length
raise IndexError, "index #{args[0]} out of string"
end
b = self[0, pos.to_i]
a = self[pos + 1..-1]
self.replace([b, value, a].join(''))
end
return value
elsif anum == 3
pos, len, value = args
pos += self.length if pos < 0
if pos < 0 || pos > self.length
raise IndexError, "index #{args[0]} out of string"
end
if len < 0
raise IndexError, "negative length #{len}"
end
b = self[0, pos.to_i]
a = self[pos + len..-1]
self.replace([b, value, a].join(''))
return value
else
raise ArgumentError, "wrong number of arguments (#{anum} for 2..3)"
end
end
def =~(re)
re =~ self
end
def match(re, &block)
if String === re
if Object.const_defined?(:Regexp)
r = Regexp.new(re)
r.match(self, &block)
else
raise NotImplementedError, "String#match needs Regexp class"
end
else
re.match(self, &block)
end
end
end
module Comparable; end
class String
include Comparable
end