class String
include Comparable
def each_line(separator = "\n", &block)
return to_enum(:each_line, separator) unless block
if separator.nil?
block.call(self)
return self
end
raise TypeError unless separator.is_a?(String)
paragraph_mode = false
if separator.empty?
paragraph_mode = true
separator = "\n\n"
end
start = 0
string = dup
self_len = self.bytesize
sep_len = separator.bytesize
while (pointer = string.byteindex(separator, start))
pointer += sep_len
pointer += 1 while paragraph_mode && string.getbyte(pointer) == 10 block.call(string.byteslice(start, pointer - start))
start = pointer
end
return self if start == self_len
block.call(string.byteslice(start, self_len - start))
self
end
def gsub(*args, &block)
return to_enum(:gsub, *args) if args.length == 1 && !block
raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 1..2)" unless (1..2).include?(args.length)
pattern, replace = *args
plen = pattern.length
if args.length == 2 && block
block = nil
end
offset = 0
result = []
while found = self.byteindex(pattern, offset)
result << self.byteslice(offset, found - offset)
offset = found + plen
result << if block
block.call(pattern).to_s
else
self.__sub_replace(replace, pattern, found)
end
if plen == 0
result << self.byteslice(offset, 1)
offset += 1
end
end
result << self.byteslice(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 sub(*args, &block)
unless (1..2).include?(args.length)
raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 2)"
end
pattern, replace = *args
if args.length == 2 && block
block = nil
end
result = []
found = self.index(pattern)
return self.dup unless found
result << self.byteslice(0, found)
offset = found + pattern.length
result << if block
block.call(pattern).to_s
else
self.__sub_replace(replace, pattern, found)
end
result << self.byteslice(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_byte(&block)
return to_enum(:each_byte, &block) unless block
pos = 0
while pos < bytesize
block.call(getbyte(pos))
pos += 1
end
self
end
end