class String

FEATURES TODO NEXT REVISION ##

1: to_morse (maybe … limited appeal my guess) 2: encryption? (maybe a separate gem, or include a wrapper from that gem) 3: format number to engineering notation … 15530.to_eng => 1515.53e3

Constants

GS_SENTENCE_TERM
GS_TITLE_EXCEPTIONS
RGX_FLOAT
ROT_LEN
ROT_STRING

ROT_STRING = ‘ abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789?/>.<,“':;|\}]{[+=_-)(*&^%$#@!`~Ω≈ç√∫˜µ≤≥÷åß∂ƒ©˙∆˚¬…æœ∑´®†¥¨ˆøπ“‘«`¡™£¢∞§¶•ªº–≠¸˛Ç◊ı˜Â¯˘¿ÅÍÎÏ˝ÓÔÒÚÆŒ„´‰ˇÁ¨ˆØ∏”’»`⁄€‹›fifl‡°·‚—±’

R_RATED
SET_CHARS
SET_COMPACT_LEFT
SET_COMPACT_RIGHT
SET_INT_CHARS
SET_LIKE_KEEP
SET_LOWERS
SET_PARSE_CHARS
SET_SPLIT_CHARS
SET_SUB_CHARS
SET_SUP_CHARS
SET_UPPERS
SET_VERTICLE
SI_UNIT_PREFIXES
STD_ESCAPE_HASH
STD_ESCAPE_SET_RUBY

Public Class Methods

chr_uni_esc(num) click to toggle source
# File lib/gstring.rb, line 119
def self.chr_uni_esc(num)
  num = num.to_i
  return nil if num < 0
  if num < 256
    rtn = "\\x" + num.to_s(16).padto(2,'0',:left)
  elsif num < 0x10000
    rtn = "\\u" + num.to_s(16).padto(4,'0',:left)
  elsif num < 0x1000000
    rtn = "\\u" + num.to_s(16).padto(6,'0',:left)
  else
    rtn = "\\u" + num.to_s(16).padto(8,'0',:left)
  end
end
define_bracket_pair(str) click to toggle source
# File lib/gstring.rb, line 75
def self.define_bracket_pair(str)
  @@gs_bracketing_pairs[str.first] = str.last
end
inside_int_cmp(mode=true) click to toggle source

ary.sort &String::inside_int_cmp

# File lib/gstring.rb, line 80
def self.inside_int_cmp(mode=true)
  return lambda do |a,b|
    a,b = (mode) ? [a.to_s, b.to_s] : [b.to_s, a.to_s]
    if(a==b)
      0
    else
      ta = a.dup
      tb = b.dup
      rgx = /\d+/
      if (ta.find(rgx).nil? || tb.find(rgx).nil?)
        a <=> b # standard compare
      else  # int inside one or both
        rtn=0
        loop do
          if(ta==tb)
            rtn=0
            break
          end
          if(ta.empty? || tb.empty?)
            rtn = ta <=> tb
            break
          end
          la = ta.parse(rgx, :no_skip, :no_strip)
          lb = tb.parse(rgx, :no_skip, :no_strip)
          if(la != lb)
            rtn = la <=> lb
            break
          end
          if(ta.parsed != tb.parsed)
            rtn = ta.parsed.to_i <=> tb.parsed.to_i
            break
          end
        end #loop
        rtn
      end # if
    end # if
  end # lambda
end
random_password(chars=8, special="_- click to toggle source

generator does not need an instance

# File lib/gstring.rb, line 581
def self.random_password(chars=8, special="_-#!~@$%^*+=?:")
  raise "password must be at least 8 characters" if chars < 8
  low  = BitSet.lowercase_chars
  high = BitSet.uppercase_chars
  digits = BitSet.digit_chars
  special = special.to_bset rescue BitSet.new 
  all = low | high | digits | special
  a,b = low.rand(2,:array_chars)
  c,d = high.rand(2, :array_chars)
  e   = digits.rand(1, :array_chars)
  f   = special.rand(1, :array_chars)
  pswd = [a,b,c,d,e]
  pswd.push f unless (f.nil? || f.empty?)
  filler = all.rand(chars - pswd.length, :array_chars)
  filler.each do |ch|
    pswd.push ch
  end
  pswd.shuffle!
  return pswd.join ''
end
reset_bracket_pairs() click to toggle source
# File lib/gstring.rb, line 61
def self.reset_bracket_pairs
  @@gs_bracketing_pairs = 
  { 
    '[' => ']',
    '(' => ')',
    '{' => '}',
    '<' => '>'
  }
end
undefine_bracket_pair(str) click to toggle source
# File lib/gstring.rb, line 71
def self.undefine_bracket_pair(str)
  @@gs_bracketing_pairs.delete(str.first)
end

Public Instance Methods

access_mode(md=:stop, dflt=' ') click to toggle source

default char for blank? or new mode

# File lib/gstring.rb, line 1644
def access_mode(md=:stop, dflt=' ') # :swing :stick :default :rotate
  @gs_access_mode = md
  @gs_default_str = dflt
  @gs_np_pos = nil
  @gs_dir = :up
  self
end
append(*prms) click to toggle source
# File lib/gstring.rb, line 1103
def append(*prms)
  rtn = ""
  prms.each do |item|
    rtn += item.to_s
  end
  self + rtn
end
append!(*prms) click to toggle source
# File lib/gstring.rb, line 1111
def append!(*prms)
  replace self.append(*prms)
end
case_match(other) click to toggle source

non-alpha chars must match too

# File lib/gstring.rb, line 224
def case_match(other)  # true if string same size with same case at all positions
  return false if (length != other.length)
  length.times do |idx|
    if (self[idx].upcase?)
      return false unless other[idx].upcase?
    elsif (self[idx].downcase?)
      return false unless other[idx].downcase?
    else  # both must be letters at the position
      return false if self[idx] != other[idx]
    end
  end
  return true
end
clean?(rgx = R_RATED) click to toggle source
# File lib/gstring.rb, line 199
def clean?(rgx = R_RATED)
  return self.scan(rgx).empty?
end
cmp(other) click to toggle source

replace with this …

# File lib/gstring.rb, line 564
def cmp(other)
  self <=> other
end
cmpi(other) click to toggle source
# File lib/gstring.rb, line 568
def cmpi(other)
  self.upcase <=> other.upcase
end
compact(sl=SET_COMPACT_LEFT, sr=SET_COMPACT_RIGHT) click to toggle source
# File lib/gstring.rb, line 1450
def compact(sl=SET_COMPACT_LEFT, sr=SET_COMPACT_RIGHT)
  #sl = sl.to_bset
  #sr = sr.to_bset
  rtn = ""
  state = :start
  each_char do |ch|
    if :start == state
      next if ch <= ' '
      state = state = sr.include?(ch) ? :right : :add
      rtn += ch
    elsif :add == state
      if ch <= ' '
        state = :zap
        rtn += ' '
      elsif sr.include? ch
        state = :right
        rtn += ch
      else
        rtn += ch  
      end
    elsif :right == state
      unless ch <= ' '
        rtn += ch
        state = sr.include?(ch) ? :right : :add
      end
    else        
    #elsif :zap == state
      next if ch <= ' '
      rtn.pop if sl.include? ch
      # state = :add
      state = sr.include?(ch) ? :right : :add
      rtn += ch
    end
  end
  rtn.pop if rtn.last==' '
  return rtn    
end
compact!(sl=SET_COMPACT_LEFT, sr=SET_COMPACT_RIGHT) click to toggle source
# File lib/gstring.rb, line 1488
def compact!(sl=SET_COMPACT_LEFT, sr=SET_COMPACT_RIGHT)
  replace compact(sl, sr)
end
condense() click to toggle source
# File lib/gstring.rb, line 409
def condense
  dup.condense!
end
condense!() click to toggle source
# File lib/gstring.rb, line 393
def condense!
  strip!
  str = ""
  sp = false
  each_char do |ch|
    if (ch <= ' ')
      sp = true
    else
      str += sp ? ' ' + ch : ch
      sp = false
    end  
  end
  replace str
  self
end
cross_match(pat) click to toggle source
# File lib/gstring.rb, line 345
def cross_match(pat)
  s_ptr=0
  p_ptr=0
  ch = ''
  return nil unless pat.class==String
  return false if empty?
  return false if pat.empty?
  loop do
    return true  if s_ptr >= self.length
    return false if p_ptr >= pat.length
    if ch != ''
      if ch==self[s_ptr]
        ch=""
        s_ptr +=1
        p_ptr +=1
        if s_ptr >= self.length
          return false if pat[p_ptr]=='+'
        end
      else
        s_ptr +=1
        return false if s_ptr >= self.length # ran out before match
      end
    elsif (pat[p_ptr]=='_')
      p_ptr+=1
      s_ptr+=1        
    elsif (pat[p_ptr]=='+')
      s_ptr+=1  # skip next letter
      p_ptr+=1
      ch = pat[p_ptr]
      return true if (ch.nil? || ch=='')  #end of the line
    elsif (pat[p_ptr]=='*')
      p_ptr+=1
      ch = pat[p_ptr]
      return true if (ch.nil? || ch=='') #end of the line
    elsif (pat[p_ptr]=='`')
      p_ptr+=1
      return false unless pat[p_ptr]==self[s_ptr]
      p_ptr+=1
      s_ptr+=1                
    else # compare chars
      return false unless pat[p_ptr]==self[s_ptr]
      p_ptr+=1
      s_ptr+=1        
    end
  end
  return true
end
cryptogram(dat=nil) click to toggle source
# File lib/gstring.rb, line 304
def cryptogram(dat=nil)  # nil==> encode, string==>test for match
  if (dat.nil?)
    rtn = dup
    set = BitSet.lowercase_chars
    off_limits = []
    skey = nil
    ary = (self.downcase.to_bset & String::SET_LOWERS).to_a(false).shuffle
    loop do
      break if ary.empty?
      skey = ary.pop
      hits = find_all(skey,:ignore) - off_limits
      off_limits = (off_limits | hits).sort
      # edge case, set only has 1 element in it
      rpw = (set.count==1) ? set.to_s : (set - skey).rand(1,:string)
      set -= rpw #can only use an element once
      hits.each do |pos|
        rtn.swapchar(pos, rpw, :casehold)
      end
    end
    return rtn      
  elsif (dat.class==String)
    return false if self.length != dat.length
    s1 = self.downcase.to_bset & BitSet.lowercase_chars
    s2 = dat.downcase.to_bset & BitSet.lowercase_chars
    return false if s1.count != s2.count
    ary1 = self.downcase.find_all(s1)
    ary2 = dat.downcase.find_all(s2)
    return false if ary1 != ary2
    return false unless case_match(dat)
    length.times do |idx|  # ::TODO:: find faster way ...
      ary1 = self.find_all(self[idx],:ignore)
      ary2 = dat.find_all(dat[idx],:ignore)
      return false if ary1 != ary2
    end
    return true
  else
    return nil
  end
  nil
end
dec(val=nil) click to toggle source
# File lib/gstring.rb, line 1080
def dec(val=nil)
  return dup.dec!(val)
end
dec!(val=nil) click to toggle source
# File lib/gstring.rb, line 1070
def dec!(val=nil)
  num = extract_trailing_int!
  return self if num.nil?
  return self if 0==num
  val ||= 1
  return self if (num-val) < 0
  append!(num-val)
  dup
end
downcase?() click to toggle source
# File lib/gstring.rb, line 210
def downcase?
  set = self.to_bset
  return false if String::SET_UPPERS ** set    # may not have any lower
  return nil unless String::SET_LOWERS ** set  # must have at least one lower
  return true
end
duplicates() click to toggle source
# File lib/gstring.rb, line 452
def duplicates
  str = self.sort
  set = BitSet.new
  rtn = ""
  last_chr = ""
  str.each_char do |ch|
    if last_chr == ch
      unless set.include? ch
        rtn += ch
      end
      set.add! ch
    end
    last_chr = ch
  end
  return rtn
end
duplicates?() click to toggle source
# File lib/gstring.rb, line 446
def duplicates?
  set = self.to_bset
  return false if set.count == length
  return true    
end
each_ord() { |ord| ... } click to toggle source
# File lib/gstring.rb, line 480
def each_ord
  unless block_given?
    enu = Enumerator.new do |y|
      self.each_char do |ch|
        y << ch.ord
      end
    end
    return enu
  end
  self.each_char do |ch|
    yield ch.ord
  end
end
enclose(pairs, escape=nil, set=String::STD_ESCAPE_SET_RUBY, hash=String::STD_ESCAPE_HASH) click to toggle source
# File lib/gstring.rb, line 712
def enclose(pairs, escape=nil, set=String::STD_ESCAPE_SET_RUBY, hash=String::STD_ESCAPE_HASH)
  return self if pairs.empty?
  if escape.nil?
    return pairs.first + self + pairs.last
  else # look for pairs.first , and replace with {escape}{pairs.first}
    str = pairs.first
    self.each_char do |ch|
      if set.include? ch
        idx = (set & ch).to_a.first
        if (ch ** (set-[0..31]))
          #byebug
          str += "\\" + ch
        elsif hash.include? idx
          #byebug
          str += hash[idx]
        else  # use hex format
          str += String.chr_uni_esc(idx)
        end
      else
        str += ch
      end        
    end
    return str + pairs.last
    #str = self.gsub(pairs.first) { escape + pairs.first }
    #return pairs.first + str + pairs.last
  end
end
enclose!(pairs, escape=nil) click to toggle source
# File lib/gstring.rb, line 740
def enclose!(pairs, escape=nil)
  replace enclose(pairs, escape)
end
eqli?(other) click to toggle source
# File lib/gstring.rb, line 572
def eqli?(other)
  self.upcase == other.upcase
end
equali?(other) click to toggle source
# File lib/gstring.rb, line 576
def equali?(other)
  self.upcase == other.upcase
end
extract(prm) click to toggle source
# File lib/gstring.rb, line 708
def extract(prm)
  return dup.extract!(prm, '')
end
extract!(prm=1, fill_hole="") click to toggle source
# File lib/gstring.rb, line 635
def extract!(prm=1, fill_hole="")
  return "" if empty?
  if prm.kind_of? Integer  # extract fron-end of string
    return "" if prm < 1
    prm =  prm > length ? length : prm
    rtn = self[0..(prm-1)]
    # replace( fill_hole + self[prm..-1] )  # WRONG!   ... we only want the same number of fill
    replace( fill_hole[0..(prm-1)] + self[prm..-1] )
    return rtn
  elsif prm.class == Range
    start  = prm.first < 0 ? self.length + prm.first : prm.first
    finish = prm.last < 0 ? self.length + prm.last : prm.last
    if (start <= finish) # normal forward order
      return "" if start >= length
      finish = finish >= length ? length-1 : finish
      return extract!(finish+1, fill_hole) if start==0  # was extract without the '!'
      rtn = self[start..finish]
      replace(self[0..(start-1)] + fill_hole + self[(finish+1)..-1])
      return rtn
    else # reverse order
      return "" if finish >= length
      start = start >= length ? length - 1 : start
      rtn = self[finish..start].reverse
      if(finish==0)
        replace(fill_hole + self[(start+1)..-1])
      else
        replace(self[0..(finish-1)] + fill_hole + self[(start+1)..-1])
      end
      return rtn
    end
  elsif prm.class == Array
    rtn = ""
    # first count number of substitutions
    cnt = 0
    prm.each do |item|
      if item.kind_of? Integer
        cnt += 1
      else
        cnt += item.count
      end
    end
    filler = fill_hole.padto(cnt, "\000", :right, :no_trunc) # use null as place holder
    prm.each do |item|
      if item.kind_of? Integer
        pos = item < 0 ? 0 : item
        if pos < length
          rtn += self[pos]
          self[pos]=filler.first!          
        end  # ignore if out of range
      else # use recursion
        str = self.extract!(item, filler)
        rtn += str
        filler.extract! str.length  # remove and discard
      end  
    end
    remove! "\000".to_bset
    return rtn 
  else # convert to set
    ary = (prm.to_bset & (0..(self.length-1))).to_a  #ignore everything out of range
    fill=fill_hole.dup
    rtn = ""
    oft = 0
    ary.each do |idx|
      ch = fill.extract!
      rtn += self[idx-oft]
      self[idx-oft]=ch
      oft+=1 if ch.empty?
    end
    return rtn
  end
  return ""
end
extract_leading_set!(set) click to toggle source
# File lib/gstring.rb, line 1123
def extract_leading_set!(set)
  rtn = ""
  set = set.to_bset
  while set.include? first do
    rtn += first!
  end  
  return rtn
end
extract_num!() click to toggle source
# File lib/gstring.rb, line 1375
def extract_num!
  dat = parse(String::RGX_FLOAT, :no_skip)
  if parsed.nil?  # no number found
    num = dat.extract_leading_set!(BitSet.digit_chars)
    replace dat
    return 0 if num.empty?
    return num.to_i
  else
    return parsed.to_f
  end  
end
extract_trailing_int!() click to toggle source
# File lib/gstring.rb, line 1059
def extract_trailing_int!
  return nil if empty?
  return nil unless String::SET_INT_CHARS.include? last
  str = ""
  while String::SET_INT_CHARS.include? last
    str += last!
    break if empty?
  end
  return str.reverse.to_i
end
extract_trailing_set!(set) click to toggle source
# File lib/gstring.rb, line 1132
def extract_trailing_set!(set)
  rtn = ""
  set = set.to_bset
  while set.include? last do
    rtn += last!
  end  
  return rtn.reverse
end
find(search,from=0,*options)
Alias for: index
find_all(obj, *modes) click to toggle source
# File lib/gstring.rb, line 262
def find_all(obj, *modes)  # returns an array of all positions of obj in self
  pos = 0
  ary = []
  loop do
    pos = self.index(obj, pos, *modes)
    break if pos.nil?
    ary.push pos
    pos +=1       
  end
  return ary
end
find_near(pos, obj=String::SET_SPLIT_CHARS, *flags) click to toggle source
# File lib/gstring.rb, line 274
def find_near(pos, obj=String::SET_SPLIT_CHARS, *flags)
  p_r = self.index(obj, pos, *flags)
  p_l = self.rindex(obj, pos, *flags)
  return [p_l,p_r]   
end
find_nth(obj, nth, *modes) click to toggle source
# File lib/gstring.rb, line 280
def find_nth(obj, nth, *modes)
  return nil if 0==nth
  if nth > 0 
    pos = 0
    loop do
      nth -= 1
      pos = self.index(obj, pos, *modes)
      return nil if pos.nil?
      return pos if nth.zero?
      pos += 1
    end
  else
    nth = -nth
    pos = length
    loop do
      nth -= 1
      pos = self.rindex(obj, pos, *modes)
      return nil if pos.nil?
      return pos if nth.zero?
      pos -= 1
    end    
  end
end
first() click to toggle source
# File lib/gstring.rb, line 1028
def first
  return "" if empty?
  self[0]
end
first!() click to toggle source

removes first char

# File lib/gstring.rb, line 1039
def first!
  return "" if empty?
  rtn = self[0]
  replace self[1..(length-1)]
  return rtn
end
gs_titlecase() click to toggle source
# File lib/gstring.rb, line 1163
def gs_titlecase
  downcase!
  if index(GS_SENTENCE_TERM)
    ary = self.split_on_set(GS_SENTENCE_TERM)
    pa = []
    ary.first.each do |sentence|
      pa.push(sentence.gs_titlecase.strip)
    end
    ary[0] = pa.reverse!
    ary[1].reverse!
    rtn = ary.first.pop
    until ary.first.empty?
      rtn += "#{ary[1].pop} #{ary.first.pop}"
    end
    rtn += ary.last || ""
    return rtn
  end
  ary = self.split(' ')
  ary.first.capitalize!
  ary.last.capitalize!
  (1..(ary.size-2)).each do |idx|
    ary[idx].capitalize! unless GS_TITLE_EXCEPTIONS.include?(ary[idx]) 
  end
  return ary.join ' '
end
gs_titlecase!() click to toggle source
# File lib/gstring.rb, line 1189
def gs_titlecase!
  replace gs_titlecase 
end
histogram() click to toggle source
# File lib/gstring.rb, line 438
def histogram
  hash = {}
  self.split('').sort.each do |ch|
    hash[ch] = hash[ch].nil? ? 1 : 1 + hash[ch]
  end
  return hash
end
ignore_me() click to toggle source
# File lib/gstring.rb, line 854
def ignore_me
  self
end
inc(val=nil) click to toggle source
# File lib/gstring.rb, line 1099
def inc(val=nil)
  return dup.inc!(val)
end
inc!(val=nil) click to toggle source

increments integer at end of string

# File lib/gstring.rb, line 1085
def inc!(val=nil)
  num = extract_trailing_int!
  if num.nil?
    if val.nil?
      append!(0)
    else
      append!(val)
    end
  else
    append! (val.nil? ? (num+1) : (num+val))
  end
  dup
end
indent() click to toggle source
# File lib/gstring.rb, line 765
def indent
  cnt = 0
  each_char do |ch|
    break if ch > ' '
    cnt += 1
  end
  cnt
end
indent!() click to toggle source
# File lib/gstring.rb, line 774
def indent!
  rtn = indent
  lstrip!
  return rtn
end
index(search,from=0,*options) click to toggle source
# File lib/gstring.rb, line 948
def index(search,from=0,*options)
  while options.first.class==Array
    options = options.first      
  end
  if (search.class==String)
    return self.downcase.index(search.downcase,from) if (options.include? :ignore)
    return old_string_index_method_4gstring(search,from)  
  end
  
  if search.class==Array
    best = nil
    search.each_with_index do |item,idx|
      pos = index(item,from,options)
      unless pos.nil?
        @best ||= idx
        best ||= pos
        if pos < best
          best = pos 
          @best = idx
        end
      end
    end
    return best  # parse uses this to know which item was found
  end

  # call this for unrecognized options
  return old_string_index_method_4gstring(search,from) unless search.class == BitSet
  if options.include? :ignore
    return self.downcase.index(search.add_opposing_case,from)
  end
  if (from < 0)
    from = length + from
  end
  from = 0 if from < 0
  ((from)...(length)).each do |ptr|
    return ptr if search.include? self[ptr]
  end
  return nil
end
keep(ks) click to toggle source
# File lib/gstring.rb, line 623
def keep(ks) # only keep chars belonging to set
  rtn = ""
  self.each_char do |ch|
    rtn += ch if ks.include? ch
  end  
  return rtn
end
keep!(ks) click to toggle source
# File lib/gstring.rb, line 631
def keep!(ks)
  replace keep(ks)
end
last() click to toggle source
# File lib/gstring.rb, line 1033
def last
  return "" if empty?
  self[length-1]
end
last!() click to toggle source

removes last char

# File lib/gstring.rb, line 1047
def last!
  if length==1
    rtn = dup
    self.clear
    return rtn
  end
  return "" if empty?
  rtn = self[length-1]
  replace self[0..(length-2)]
  return rtn
end
like(table_class_name, table_column_name, mode_and=true, kp = SET_LIKE_KEEP) click to toggle source
# File lib/gstring.rb, line 173
def like(table_class_name, table_column_name, mode_and=true, kp = SET_LIKE_KEEP)
  ary = []
  self.split.each do |substr|
    str =  substr.keep kp
    if (str.first=='*')
      str.first!
      if (str.last=='*')
        str.last!
        ary.push "%#{str}%".gsub('*', '%')
      else
        ary.push "%#{str}".gsub('*', '%')
      end
    elsif (str.last=='*')
      str.last!
      ary.push "#{str}%".gsub('*', '%')
    else
      ary.push "%#{str}%".gsub('*', '%')
    end
  end #each
  md = mode_and ? ' and ' : ' or '
  qry = (["`#{table_column_name}` like ?"] * ary.count).join md
  return table_class_name.where(qry, *ary)
end
limit_to(size, *flags) click to toggle source
# File lib/gstring.rb, line 1563
def limit_to(size, *flags)
  size = length + size + 1 if size < 0
  if flags.first.kind_of? Integer
    flags=flags.dup
    cnt=flags.reverse!.pop
    pos = find_nth(SET_VERTICLE,cnt,*flags)
    if pos && (pos < size)
      size = pos + 1
    end
  end
  return self if length <= size
  if flags.include? :no_break
    pos = self.rfind(SET_SPLIT_CHARS,size-1)
    return self[0..(size-2)] + '…' if pos.nil?
    return self[0..(pos-1)] + '…'       
  else
    return self[0..(size-2)] + '…'
  end
end
limit_to!(size, *flags) click to toggle source
# File lib/gstring.rb, line 1583
def limit_to!(size, *flags)
  replace limit_to(size, *flags)
end
mixedcase?() click to toggle source
# File lib/gstring.rb, line 217
def mixedcase?
  set = self.to_bset
  return nil unless set ** (String::SET_LOWERS | String::SET_UPPERS) # must have a letter
  return (set ** String::SET_LOWERS) && (set ** String::SET_UPPERS) 
end
next() click to toggle source
# File lib/gstring.rb, line 1652
def next
  @gs_np_pos ||= nil
  @gs_access_mode ||= :stop
  @gs_dir ||= :up
  return "" if empty?
  if @gs_np_pos.nil?
    ch = first
    @gs_np_pos = 0
    return ch
  else
    case @gs_access_mode
      when :stop
        @gs_np_pos = @gs_np_pos >= length ? length : @gs_np_pos + 1
        ch = self[@gs_np_pos]
        return ch.nil? ? "" : ch
      when :rotate
        @gs_np_pos += 1
        @gs_np_pos = @gs_np_pos >= length ? 0 : @gs_np_pos
        return self[@gs_np_pos]
      when :stick
        @gs_np_pos = @gs_np_pos >= length ? length : @gs_np_pos + 1
        ch = self[@gs_np_pos]
        return ch.nil? ? last : ch
      when :default
        @gs_np_pos = @gs_np_pos >= length ? length : @gs_np_pos + 1
        ch = self[@gs_np_pos]
        return ch.nil? ? @gs_default_str : ch
      when :swing
        return first if length==1
        if @gs_dir== :up
          @gs_np_pos += 1
          if @gs_np_pos >= length
            @gs_dir= :down
            @gs_np_pos = length - 2
          end
          return self[@gs_np_pos]            
        else # :down
          @gs_np_pos -= 1
          if @gs_np_pos < 0
            @gs_dir= :up
            @gs_np_pos = 1
          end
          return self[@gs_np_pos]
        end
      else
        raise "unsupported access mode"  
    end
  end
end
old_string_index_method_4gstring(search,from=0,*options)
##

Updates to existing index, rindex methods # now accepts search types of: Set, Array #

##
Alias for: index
old_string_rindex_method_4gstring(search,from=-1,*options)
Alias for: rindex
padto(tar, *prms) click to toggle source
::todo

Add flags :rotate, :stick

# File lib/gstring.rb, line 782
def padto(tar, *prms)
  return self if length == tar
  prms = prms.first if prms.first.kind_of? Array
  with = ' '
  flags = []
  how = :left
  prms.each do |prm|
    if prm.kind_of? String
      with=prm
      next
    end
    case prm
      when :no_trunc, :rotate, :stick, :space, :swing
        flags.push prm
      when :left, :right, :both
        how = prm
      else
        raise "padto unknown parameter"
    end
  end
  if length > tar
    return self if flags.include? :no_trunc
    return "" if tar<=0
    return '…' if tar==1
    return self[0..(tar-2)]+'…'
  end
  with = ' ' if with.empty?
  rtn = ""
  flags -= [:no_trunc]
  flag = flags.empty? ? :stick : flags.first
  with.access_mode(flag==:space ? :default : flag)
  case how
    when :right
      rtn = self
      (tar-length).times do |xx|        
        rtn += with.next
      end
    when :both
      lp = (tar-length) >> 1
      rp = (tar-length) - lp
      str = ""
      (rp).times do |xx|
        str += with.next
      end
      rtn = str[0..(lp-1)].reverse + self + str
    else # :left
      str = ""
      (tar-length).times do |xx|
        str += with.next
      end
      rtn += str.reverse + self
  end
  rtn
end
padto!(tar, *flags) click to toggle source
# File lib/gstring.rb, line 837
def padto!(tar, *flags)
  replace padto(tar, flags)
end
parse(search_key = String::SET_PARSE_CHARS, *options) click to toggle source
# File lib/gstring.rb, line 858
def parse(search_key = String::SET_PARSE_CHARS, *options)
  options = options.first if options.first.class==Array
  meth = options.include?(:no_strip) ? :ignore_me : :strip
  rtn=""
  @found = nil
  if(search_key.class==BitSet)
    #skip over first char
    idx = options.include?(:no_skip) ? 0 : 1
    sk = options.include?(:ignore) ? search_key.add_opposing_case : search_key
    sf = idx
    self[sf...length].each_char do |ch|
      if(sk.include? ch)
        @found=ch
        break
      end
      idx += 1
    end 
    unless @found.nil?
      rtn = (idx==0) ? "" : self[0..(idx-1)].send(meth)
      replace self[(idx+1)..-1].send(meth)
      return rtn
    end
    rtn = clone
    clear
    return rtn
  elsif (search_key.class == Regexp)
    sf = options.include?(:no_skip) ? 0 : 1
    pos = index(search_key,sf)
    @found = pos.nil? ? nil : self.match(search_key)[0]
    if pos.nil?
      rtn = clone
      clear
      return rtn
    else # found
      rtn = pos.zero? ? "" : self[0..(pos-1)].send(meth)
      replace self[(pos+@found.length)..length].send(meth)
      return rtn
    end
  elsif (search_key.class == String)
    #skip over first char unless option specifies :no_skip
    sf = options.include?(:no_skip) ? 0 : 1
    idx = index(search_key,sf,options)
    if idx.nil?
      rtn = clone
      clear
      return rtn
    else
      rtn = idx.zero? ? "" : self[0..(idx-1)].send(meth)
      @found = self[idx..(idx+search_key.length-1)]
      replace self[(idx+search_key.length)..length].send(meth)
      return rtn
    end
  elsif (search_key.class == Array)
    shortest = nil
    best = nil
    start = options.include?(:no_skip) ? 0 : 1
    search_key.each_with_index do |val,idx|
      pos = self.index(val,start,options)
      unless pos.nil?
        best = idx if best.nil?
        shortest ||= pos
        if (pos < shortest)
          shortest = pos
          best = idx
        end
      end
    end
    if shortest.nil?
      rtn = clone
      clear
      return rtn
    else
      #opt = options.dup
      #opt[:no_skip]=true
      #return parse(search_key[best],opt)
      return parse(search_key[best],options)
    end        
  else  # we are passed something that should have been converted to a set
    return parse([search_key].to_bset,options)
  end
end
parsed() click to toggle source
# File lib/gstring.rb, line 1119
def parsed
  @found ||= nil
end
php_substr(pos=0,len=nil) click to toggle source

negative len means position from right to left positive len means number of chars to capture exception if pos and len are both negative and pos > len … then starting point is the |sum| from the right, and length … and the ending point is also the |sum| ??? need more examples

# File lib/gstring.rb, line 846
def php_substr(pos=0,len=nil)
  return "" if len==0
  len = len.nil? ? length : len
  r_s = (pos >= 0) ? pos : pos + length
  r_e = (len >= 0) ? r_s + len - 1 : len + length - 1
  return self[(r_s)..(r_e)]
end
pop(nchars=1) click to toggle source
# File lib/gstring.rb, line 417
def pop(nchars=1)
  if (nchars < 1) # avoid silly requests
    return ""
  elsif (nchars >= length)
    rtn = dup
    replace ""
    return rtn
  end
  rtn = self[-nchars..-1]
  replace self[0..(length-nchars-1)]
  return rtn
end
prev() click to toggle source
# File lib/gstring.rb, line 1702
def prev
  @gs_np_pos ||= nil
  @gs_access_mode ||= :stop
  @gs_dir ||= :up
  return "" if empty?
  if @gs_np_pos.nil?
    ch = last
    @gs_np_pos = length - 1
    return ch
  else
    case @gs_access_mode
      when :stop
        @gs_np_pos = @gs_np_pos <= 0 ? -1 : @gs_np_pos - 1
        return "" if @gs_np_pos < 0
        return self[@gs_np_pos]
      when :rotate
        @gs_np_pos -= 1
        @gs_np_pos = @gs_np_pos < 0 ? length-1 : @gs_np_pos
        return self[@gs_np_pos]
      when :stick
        @gs_np_pos = @gs_np_pos <= 0 ? -1 : @gs_np_pos - 1
        return first if @gs_np_pos < 0
        return self[@gs_np_pos]
      when :default
        @gs_np_pos = @gs_np_pos <= 0 ? -1 : @gs_np_pos - 1
        return @gs_default_str if @gs_np_pos < 0
        return self[@gs_np_pos]
      when :swing
        return first if length==1
        if @gs_dir== :down
          @gs_np_pos += 1
          if @gs_np_pos >= length
            @gs_dir= :up
            @gs_np_pos = length - 2
          end
          return self[@gs_np_pos]            
        else # :up
          @gs_np_pos -= 1
          if @gs_np_pos < 0
            @gs_dir= :down
            @gs_np_pos = 1
          end
          return self[@gs_np_pos]
        end
      else
        raise "unsupported access mode"            
    end
  end
end
push(str) click to toggle source
# File lib/gstring.rb, line 413
def push(str)
  replace(self+str).dup
end
rand(cnt=1, *prms) click to toggle source
# File lib/gstring.rb, line 1603
def rand(cnt=1, *prms)
  return "" if empty?
  return "" if cnt < 1
  if length==1
    return self if prms.include? :set
    return self * cnt
  end
  rnd = Random.new
  rtn = ""
  str = prms.include?(:set) ? self.to_bset.to_s : self.dup
  cnt.times do
    break if str.empty?
    ch = str[rnd.rand(str.length)]
    rtn += ch
    str[str.find(ch)] = "" if prms.include? :once      
  end
  return rtn
end
rand!(cnt=1, *prms) click to toggle source
# File lib/gstring.rb, line 1622
def rand!(cnt=1, *prms)  # once is implied
  return "" if empty?
  return "" if cnt < 1
  if length==1
    return first!
  end
  rnd = Random.new
  rtn = ""
  cnt.times do
    break if self.empty?
    ch = self[rnd.rand(self.length)]
    rtn += ch
    if prms.include? :set
      remove! ch.to_bset
    else
      self[self.find(ch)] = ""
    end
  end
  return rtn
end
rehash() click to toggle source
# File lib/gstring.rb, line 494
def rehash  # more consistent hash method
  sum = 0
  tr = 4294967296
  rL = Random.new(self.length)
  sum = rL.rand(tr)
  self.each_char do |ch|
    rt = Random.new(ch.ord)
    sum += rt.rand(tr)
    sum ^= rL.rand(sum)
  end
  return sum & (tr-1)
end
remove(obj, *prm) click to toggle source
# File lib/gstring.rb, line 617
def remove(obj, *prm) # remove all characters
  str = dup
  str.remove!(obj, *prm)
  return str    
end
remove!(obj, *prm) click to toggle source
# File lib/gstring.rb, line 602
def remove!(obj, *prm) # remove all characters
  flags = prm.dup
  flags |= [:no_skip, :no_strip]
  rtn = ""
  str = ""
  loop do
    str += parse(obj,flags)
    break if parsed.nil?
    rtn += parsed      
  end
  str += self
  replace str
  return rtn
end
rfind(search,from=-1,*options)
Alias for: rindex
rindex(search,from=-1,*options) click to toggle source
# File lib/gstring.rb, line 988
def rindex(search,from=-1,*options)
  options = options.first if options.first.class==Array
  if (search.class==String)
    return self.downcase.rindex(search.downcase,from) if (options.include? :ignore)
    return old_string_rindex_method_4gstring(search,from)  
  end
  
  if search.class==Array
    best = nil
    search.each_with_index do |item,idx|
      pos = rindex(item,from,options)
      unless pos.nil?
        @best ||= idx
        best ||= pos
        if pos > best
          best = pos 
          @best = idx
        end
      end
    end
    return best  # parse uses this to know which item was found
  end
  
  # call this for unrecognized options
  return old_string_rindex_method_4gstring(search,from) unless search.class == BitSet
  if options.include? :ignore
    return self.downcase.rindex(search.add_opposing_case,from)
  end
  idx = (from < 0) ? length + from : from
  return nil if idx < 0
  until (search.include? (self[idx])) do
    idx -= 1
    return nil if idx < 0
  end
  return idx
end
rot_crypt(pswd="Standard Password should never be used!") click to toggle source
# File lib/gstring.rb, line 507
def rot_crypt(pswd="Standard Password should never be used!")
  raise "illegal password" if pswd.empty?
  rtn = ""
  ptr = 0
  rnd = Random.new(pswd.rehash)
  len = pswd.length
  self.each_char do |ch|
    ss = @@rot_hash[ch]
    if ss.nil?  # make no subs
      rtn += ch
    else
      # pos = (ch.ord + pswd[ptr].ord + rnd.rand(ROT_LEN)) % ROT_LEN
      pos = (ss + pswd[ptr].ord + rnd.rand(ROT_LEN)) % ROT_LEN
      rtn += ROT_STRING[pos]
    end
    ptr += 1
    ptr = 0 if ptr >= len
  end
  return rtn
end
rot_decrypt(pswd="Standard Password should never be used!") click to toggle source
# File lib/gstring.rb, line 528
def rot_decrypt(pswd="Standard Password should never be used!")
raise "illegal password" if pswd.empty?
  rtn = ""
  ptr = 0
  rnd = Random.new(pswd.rehash)
  len = pswd.length
  self.each_char do |ch|
    ss = @@rot_hash[ch]
    if ss.nil?  # make no subs
      rtn += ch
    else
      pos = @@rot_hash[ch]  # got back the number
      pos = pos - pswd[ptr].ord - rnd.rand(ROT_LEN)
      pos = pos % ROT_LEN
      # rtn += pos.chr(Encoding::UTF_8)
      rtn += ROT_STRING[pos]
    end
    ptr += 1
    ptr = 0 if ptr >= len
  end
  return rtn
end
shuffle() click to toggle source
# File lib/gstring.rb, line 1193
def shuffle
  return self.split('').shuffle.join
end
shuffle!() click to toggle source
# File lib/gstring.rb, line 1197
def shuffle!
  replace shuffle
end
sort() click to toggle source
# File lib/gstring.rb, line 430
def sort
  self.split('').sort.join('')
end
sort!() click to toggle source
# File lib/gstring.rb, line 434
def sort!
  replace self.split('').sort.join('')
end
split_on_set(set=' ') click to toggle source
# File lib/gstring.rb, line 1141
def split_on_set(set=' ')
  str = dup
  if (set.nil? || set.empty?)
    set = ' '
  end
  set = set.to_bset
  prefx = str.extract_leading_set!(set)
  pstfx = str.extract_trailing_set!(set)
  dat = []
  tok = []
  loop do
    break if str.empty?
    dat.push str.parse(set, :no_strip)
    tmp = str.parsed
    break if tmp.nil? 
    tmp += str.extract_leading_set!(set)
    tok.push tmp
  end
  dat.push str unless str.empty?
  return [dat,tok,prefx,pstfx]
end
sublist(*prms) click to toggle source
# File lib/gstring.rb, line 1201
def sublist(*prms)
  if (prms.first.class==Symbol)
    if prms.first == :bang
      prms = prms[1] 
    else
      raise "illegal sublist parameter"
    end
  end
  prms.reverse!
  cls = prms.pop
  flags = {}
  dflt = nil
  subh = nil  # substitution hash
  suba = nil  # substitution array
  cnt = nil
  until prms.empty?
    tmp = prms.pop
    if(tmp.class==Array)
      raise "parameter error" unless suba.nil?
      suba = tmp.reverse  # make it easy to pop, and makes a new instance
    elsif (tmp.class==Hash)
      raise "parameter error" unless subh.nil?
      subh = {}
      tmp.each do |key,val|
        subh[key.to_s] = val.to_s  # convert keys and values to strings
      end      
    elsif (tmp.class==Symbol)
      flags[tmp] = true
    elsif (tmp.class==Fixnum)
      raise "count parameter repeated" unless cnt.nil?
      cnt = tmp
    elsif (tmp.class==String)
      raise "parameter error" unless dflt.nil?
      dflt = tmp      
    else
      raise "unknown parameter type"
    end
  end

  str = self.dup
  ptr = 0
  rtn = ""
  cls = [cls] if (String==cls.class)
  fa = []
  # add more as needed later ...
  fa.push :ignore if flags.include? :ignore
  fass = fa + [:no_strip] + [:no_skip]   
  cls = [cls] if (BitSet==cls.class)     # push everything into an array even regx
  cls = [cls] if (Regexp==cls.class)
  flst = (flags.include? :first) ? {} : nil

  # remove nil values
  subh ||= {}
  suba ||= []
  dflt ||= ""
  
  if flags.include? :ignore  # update substitution hash keys to lower case if :ignore
    unless subh.empty?
      tmp = {}
      subh.each do |key,val|
        tmp[key.downcase] = val.to_s
      end
      subh = tmp
    end    
  end
  
  unless (Hash==cls.class)
    loop do
      unless cnt.nil?
        if (cnt <= 0)
          rtn += str
          return rtn
        end
      end
      rtn += str.parse(cls, fass)  # make sure we are working on arrays of a bunch of stuff including nested === add test case
      break if str.parsed.nil?
      
      unless flst.nil?  # process first flag exceptions
        key = (flags.include? :ignore) ? str.parsed.downcase : str.parsed 
        if flst.include? key
          rtn += str.parsed  # make no substitution
          cnt -= 1 unless cnt.nil?
          next
        else
          flst[key] = true   # mark as taboo on future substitutions
        end
      end
      
      # first check to see if we have a hash match
      unless subh.empty?
        key = (flags.include? :ignore) ? str.parsed.downcase : str.parsed
        dat = subh[key]
        unless dat.nil?
          rtn += dat
          return rtn if str.empty?
          cnt -= 1 unless cnt.nil?
          next
        end           
      end

      # next check to see if we have substitution data in the array
      unless suba.empty?
        rtn += suba.pop
        return rtn if str.empty?
        cnt -= 1 unless cnt.nil?
        next
      end
      
      # at last use the default
      if flags.include? :stop  # do not make substitutions with default
        rtn += str.parsed
        rtn += str
        return rtn
      elsif flags.include? :skip  # skip over, then keep going
        rtn += str.parsed
      else
        rtn += dflt  
      end
      return rtn if str.empty?
      cnt -= 1 unless cnt.nil?
    end # loop
    return rtn 
  else # (Hash==cls.class)
    cls = cls.dup
    loop do
      unless cnt.nil?
        if (cnt <= 0)
          rtn += str
          return rtn
        end
      end
      pos = nil
      best = nil
      bval = nil
      cls.each do |key,val|
        idx = str.index(key.to_s, 0 , fa)
        unless idx.nil?
          pos ||= idx
          best ||= key.to_s
          bval ||= val.to_s
          if(idx < pos)
            pos = idx
            best = key.to_s
            bval = val.to_s
          end
          break if idx.zero?  # can't get better than zero, so stop looking
        end
      end
      if best.nil?
        rtn += str
        return rtn
      end
      # byebug if flags.include? :ignore
      rtn += str.parse(best, fass)
      break if str.parsed.nil?
      if flags.include? :first
        cls.delete best
        cls.delete best.to_sym  # just in case
      end
      rtn += bval  
      cnt -= 1 unless cnt.nil?
    end #loop
    return rtn
  end
end
sublist!(*prms) click to toggle source
# File lib/gstring.rb, line 1367
def sublist!(*prms)
  replace sublist(:bang, prms)
end
swapchar(pos, ch, *modes) click to toggle source
# File lib/gstring.rb, line 238
def swapchar(pos, ch, *modes)
  modes = modes.first if modes.first.class==Array
  rtn = self[pos]
  return nil if rtn.nil?
  if ch.empty?
    return nil unless modes.include? :empty_ok
  end
  unless ch.empty?
    ch = ch.first unless modes.include? :substring
  end    
  if modes.include? :casehold
    if rtn.upcase?
      self[pos]=ch.upcase
    elsif rtn.downcase?
      self[pos]=ch.downcase
    else
      self[pos]=ch.first
    end   
  else
    self[pos]=ch  # standard mode
  end
  rtn
end
to_crlf() click to toggle source
# File lib/gstring.rb, line 1387
def to_crlf
  rtn = ""
  state = :normal
  each_char do |ch|
    if :normal == state
      if "\r" == ch
        state = :r_pending
      elsif "\n" == ch
        rtn += "\r\n"
      else
        rtn += ch
      end
    else
      if "\n" == ch
        rtn += "\r\n"
      else
        rtn += "\r"
        rtn += ch
      end
      state = :normal
    end
  end
  return rtn
end
to_crlf!() click to toggle source
# File lib/gstring.rb, line 1437
def to_crlf!
  self.replace to_crlf
  self
end
to_eng(pa=6, unit=nil) click to toggle source
# File lib/gstring.rb, line 1587
def to_eng(pa=6, unit=nil)
  return self.to_f.to_eng(pa, unit)
end
to_lf() click to toggle source
# File lib/gstring.rb, line 1412
def to_lf  # convert \r\n to \n
  rtn = ""
  state = :normal
  each_char do |ch|
    if :normal == state
      if "\r" == ch
        state = :r_pending
      elsif "\n" == ch
        rtn += "\012"
      else
        rtn += ch
      end
    else
      if "\n" == ch
        rtn += "\n"
      else
        rtn += "\r"
        rtn += ch
      end
      state = :normal
    end
  end
  return rtn
end
to_lf!() click to toggle source
# File lib/gstring.rb, line 1442
def to_lf!  #  removes \r
  self.replace to_lf
  self
end
to_num() click to toggle source
# File lib/gstring.rb, line 1371
def to_num  # convert to integer or float depending on format
  self.dup.extract_num!
end
to_scd(dp=nil, delim = ',.') click to toggle source
# File lib/gstring.rb, line 1591
def to_scd(dp=nil, delim = ',.')
  num = to_num
  if(dp.nil?)
    if num.class==Float
      return num.to_scd(2,delim)
    else
      return num.to_scd(0,delim)
    end
  end
  return num.to_scd(dp,delim)  
end
to_subscript(html=false) click to toggle source
# File lib/gstring.rb, line 162
def to_subscript(html=false)
  return '<sub>' + self + '</sub>' if html
  rtn = ""
  each_char do |ch|
    rtn += String::SET_SUB_CHARS.include?(ch) ? @@gs_sub_hash[ch] : ch
  end
  return rtn
end
to_superscript(html=false) click to toggle source
# File lib/gstring.rb, line 153
def to_superscript(html=false)
  return '<sup>' + self + '</sup>' if html
  rtn = ""
  each_char do |ch|
    rtn += String::SET_SUP_CHARS.include?(ch) ? @@gs_sup_hash[ch] : ch
  end
  return rtn
end
uchr() click to toggle source
# File lib/gstring.rb, line 1752
def uchr
  first
end
unenclose(escape=nil) click to toggle source
# File lib/gstring.rb, line 744
def unenclose(escape=nil) # unescape
  return nil if length < 2
  unless first==last
    return nil unless last == @@gs_bracketing_pairs[first]
  end
  if @@gs_bracketing_pairs.include? first
    return nil if first==last
  end
  str = self[1..(length-2)]
  unless escape.nil?
    str = str.gsub(escape) { '' }  # blind removal? ... may need to rethink this a tad
  end
  return str
end
unenclose!(escape=nil) click to toggle source
# File lib/gstring.rb, line 759
def unenclose!(escape=nil)
  str = unenclose(escape)
  replace str unless str.nil?
  str.nil? ? nil : self
end
upcase?() click to toggle source
# File lib/gstring.rb, line 203
def upcase?
  set = self.to_bset
  return false if String::SET_LOWERS ** set    # may not have any lower
  return nil unless String::SET_UPPERS ** set  # must have at least one upper
  return true
end
wrap_to(len, *flags) click to toggle source
# File lib/gstring.rb, line 1494
def wrap_to(len, *flags)
  # remove this as cr will mess things up
  # the logic below will need to be inferred as needed
  #if (self.length < len)
  #  if flags.include? :array
  #    return [self.dup]
  #  else
  #    return self.dup
  #  end
  #end
  ary = []
  str = self.to_lf  # remove messy \r if present
  if flags.include? :approximate
    loop do
      tar = str.find_near(len)
      tmp = str.find("\n")
      unless tmp.nil?
        tar = [tmp,tmp] if tmp <= len
      end
      # now for the nasty end points and edge cases
      if tar.first.nil?
        if tar.last.nil?
          ary.push str.extract!(len)
        else
          ary.push str.extract!(tar.last + 1)
        end
      else
        if tar.last.nil?
          ary.push str.extract!(tar.first + 1)
        else # find closest fit
          if (len - tar.first) <= (tar.last - len)
            ary.push str.extract!(tar.first + 1)
          else
            ary.push str.extract!(tar.last + 1)
          end
        end
      end
      break if str.length <= len
    end # loop
  else
    loop do
      tar = str.rindex(String::SET_SPLIT_CHARS, len)
      tmp = str.find("\n")
      unless tmp.nil?
        tar = tmp if tmp <= len
      end        
      if (tar.nil?)
        ary.push str.extract!(len)
      else
        ary.push str.extract!(tar+1)
      end
      break if str.length <= len
    end #loop
  end #if
  ary.push str
  ary.length.times { |ii| ary[ii].strip! } unless flags.include? :no_strip
  return ary if flags.include? :array
  if flags.include? :html
    str = ary.join '<br />'
  else
    str = ary.join "\n"
  end
  return str    
end
zap!() click to toggle source
# File lib/gstring.rb, line 1115
def zap!  # simple alias
  clear
end