class String ## # call-seq: # String.try_convert(obj) -> string or nil # # Try to convert obj into a String, using to_str method. # Returns converted string or nil if obj cannot be converted # for any reason. # # String.try_convert("str") #=> "str" # String.try_convert(/re/) #=> nil # def self.try_convert(obj) if obj.respond_to?(:to_str) obj.to_str else nil end end ## # call-seq: # string.clear -> string # # Makes string empty. # # a = "abcde" # a.clear #=> "" # def clear self.replace("") end ## # call-seq: # str.lstrip -> new_str # # Returns a copy of str with leading whitespace removed. See also # String#rstrip and String#strip. # # " hello ".lstrip #=> "hello " # "hello".lstrip #=> "hello" # def lstrip a = 0 z = self.size - 1 a += 1 while a <= z and " \f\n\r\t\v".include?(self[a]) (z >= 0) ? self[a..z] : "" end ## # call-seq: # str.rstrip -> new_str # # Returns a copy of str with trailing whitespace removed. See also # String#lstrip and String#strip. # # " hello ".rstrip #=> " hello" # "hello".rstrip #=> "hello" # def rstrip a = 0 z = self.size - 1 z -= 1 while a <= z and " \f\n\r\t\v\0".include?(self[z]) (z >= 0) ? self[a..z] : "" end ## # call-seq: # str.strip -> new_str # # Returns a copy of str with leading and trailing whitespace removed. # # " hello ".strip #=> "hello" # "\tgoodbye\r\n".strip #=> "goodbye" # def strip a = 0 z = self.size - 1 a += 1 while a <= z and " \f\n\r\t\v".include?(self[a]) z -= 1 while a <= z and " \f\n\r\t\v\0".include?(self[z]) (z >= 0) ? self[a..z] : "" end ## # call-seq: # str.lstrip! -> self or nil # # Removes leading whitespace from str, returning nil if no # change was made. See also String#rstrip! and # String#strip!. # # " hello ".lstrip #=> "hello " # "hello".lstrip! #=> nil # def lstrip! raise RuntimeError, "can't modify frozen String" if frozen? s = self.lstrip (s == self) ? nil : self.replace(s) end ## # call-seq: # str.rstrip! -> self or nil # # Removes trailing whitespace from str, returning nil if # no change was made. See also String#lstrip! and # String#strip!. # # " hello ".rstrip #=> " hello" # "hello".rstrip! #=> nil # def rstrip! raise RuntimeError, "can't modify frozen String" if frozen? s = self.rstrip (s == self) ? nil : self.replace(s) end ## # call-seq: # str.strip! -> str or nil # # Removes leading and trailing whitespace from str. Returns # nil if str was not altered. # def strip! raise RuntimeError, "can't modify frozen String" if frozen? s = self.strip (s == self) ? nil : self.replace(s) end ## # call-seq: # str.casecmp(other_str) -> -1, 0, +1 or nil # # Case-insensitive version of String#<=>. # # "abcdef".casecmp("abcde") #=> 1 # "aBcDeF".casecmp("abcdef") #=> 0 # "abcdef".casecmp("abcdefg") #=> -1 # "abcdef".casecmp("ABCDEF") #=> 0 # def casecmp(str) self.downcase <=> str.to_str.downcase rescue NoMethodError raise TypeError, "no implicit conversion of #{str.class} into String" end def partition(sep) raise TypeError, "type mismatch: #{sep.class} given" unless sep.is_a? String n = index(sep) unless n.nil? m = n + sep.size [ slice(0, n), sep, slice(m, size - m) ] else [ self, "", "" ] end end def rpartition(sep) raise TypeError, "type mismatch: #{sep.class} given" unless sep.is_a? String n = rindex(sep) unless n.nil? m = n + sep.size [ slice(0, n), sep, slice(m, size - m) ] else [ "", "", self ] end end ## # call-seq: # str.slice!(fixnum) -> new_str or nil # str.slice!(fixnum, fixnum) -> new_str or nil # str.slice!(range) -> new_str or nil # str.slice!(other_str) -> new_str or nil # # Deletes the specified portion from str, and returns the portion # deleted. # # string = "this is a string" # string.slice!(2) #=> "i" # string.slice!(3..6) #=> " is " # string.slice!("r") #=> "r" # string #=> "thsa sting" # def slice!(arg1, arg2=nil) raise RuntimeError, "can't modify frozen String" if frozen? raise "wrong number of arguments (for 1..2)" if arg1.nil? && arg2.nil? if !arg1.nil? && !arg2.nil? idx = arg1 idx += self.size if arg1 < 0 if idx >= 0 && idx <= self.size && arg2 > 0 str = self[idx, arg2] else return nil end else validated = false if arg1.kind_of?(Range) beg = arg1.begin ed = arg1.end beg += self.size if beg < 0 ed += self.size if ed < 0 ed -= 1 if arg1.exclude_end? validated = true elsif arg1.kind_of?(String) validated = true else idx = arg1 idx += self.size if arg1 < 0 validated = true if idx >=0 && arg1 < self.size end if validated str = self[arg1] else return nil end end unless str.nil? || str == "" if !arg1.nil? && !arg2.nil? idx = arg1 >= 0 ? arg1 : self.size+arg1 str2 = self[0...idx] + self[idx+arg2..-1].to_s else if arg1.kind_of?(Range) idx = beg >= 0 ? beg : self.size+beg idx2 = ed>= 0 ? ed : self.size+ed str2 = self[0...idx] + self[idx2+1..-1].to_s elsif arg1.kind_of?(String) idx = self.index(arg1) str2 = self[0...idx] + self[idx+arg1.size..-1] unless idx.nil? else idx = arg1 >= 0 ? arg1 : self.size+arg1 str2 = self[0...idx] + self[idx+1..-1].to_s end end self.replace(str2) unless str2.nil? end str end ## # call-seq: # str.insert(index, other_str) -> str # # Inserts other_str before the character at the given # index, modifying str. Negative indices count from the # end of the string, and insert after the given character. # The intent is insert aString so that it starts at the given # index. # # "abcd".insert(0, 'X') #=> "Xabcd" # "abcd".insert(3, 'X') #=> "abcXd" # "abcd".insert(4, 'X') #=> "abcdX" # "abcd".insert(-3, 'X') #=> "abXcd" # "abcd".insert(-1, 'X') #=> "abcdX" # def insert(idx, str) if idx == -1 return self << str elsif idx < 0 idx += 1 end self[idx, 0] = str self end ## # call-seq: # str.ljust(integer, padstr=' ') -> new_str # # If integer is greater than the length of str, returns a new # String of length integer with str left justified # and padded with padstr; otherwise, returns str. # # "hello".ljust(4) #=> "hello" # "hello".ljust(20) #=> "hello " # "hello".ljust(20, '1234') #=> "hello123412341234123" def ljust(idx, padstr = ' ') raise ArgumentError, 'zero width padding' if padstr == '' return self if idx <= self.size pad_repetitions = (idx / padstr.length).ceil padding = (padstr * pad_repetitions)[0...(idx - self.length)] self + padding end ## # call-seq: # str.rjust(integer, padstr=' ') -> new_str # # If integer is greater than the length of str, returns a new # String of length integer with str right justified # and padded with padstr; otherwise, returns str. # # "hello".rjust(4) #=> "hello" # "hello".rjust(20) #=> " hello" # "hello".rjust(20, '1234') #=> "123412341234123hello" def rjust(idx, padstr = ' ') raise ArgumentError, 'zero width padding' if padstr == '' return self if idx <= self.size pad_repetitions = (idx / padstr.length).ceil padding = (padstr * pad_repetitions)[0...(idx - self.length)] padding + self end def chars(&block) if block_given? self.split('').each do |i| block.call(i) end self else self.split('') end end def each_char(&block) return to_enum :each_char unless block split('').each do |i| block.call(i) end self end def codepoints(&block) len = self.size if block_given? self.split('').each do|x| block.call(x.ord) end self else self.split('').map{|x| x.ord} end end alias each_codepoint codepoints ## # call-seq: # str.prepend(other_str) -> str # # Prepend---Prepend the given string to str. # # a = "world" # a.prepend("hello ") #=> "hello world" # a #=> "hello world" def prepend(arg) self[0, 0] = arg self end end