Class String
In: lib/extensions/string.rb
Parent: Object


cmp   ends_with?   expand_tabs   indent   join   line   outdent   starts_with?   taballto   tabto   trim  

Public Instance methods

Compare this string to other, returning the first index at which they differ, or nil if they are equal.

  "practise".cmp("practice")    # -> 6
  "noun".cmp("nouns")           # -> 5 (and vice versa)
  "fly".cmp("fly")              # -> nil


# File lib/extensions/string.rb, line 283
    def cmp(other)
      other = other.to_str
      if self == other
        return nil
        n = [self.size, other.size].min
        (0..n).each do |i|
          return i unless self[i] == other[i]

Returns true iff this string ends with str.

   "Hello, world".ends_with?(", world")    # -> true
   "Hello, world".ends_with?("Green")      # -> false


# File lib/extensions/string.rb, line 235
    def ends_with?(str)
      str = str.to_str
      tail = self[-str.length, str.length]
      tail == str      

Expands tabs to n spaces. Non-destructive. If n is 0, then tabs are simply removed. Raises an exception if n is negative.


# File lib/extensions/string.rb, line 48
    def expand_tabs(n=8)
      n = n.to_int
      raise ArgumentError, "n must be >= 0" if n < 0
      return gsub(/\t/, "") if n == 0
      return gsub(/\t/, " ") if n == 1
      str = self.dup
        str.gsub!(/^([^\t\n]*)(\t+)/) { |f|
          val = ( n * $2.size - ($1.size % n) )
          $1 << (' ' * val)

Indents the string n spaces.


# File lib/extensions/string.rb, line 71
    def indent(n)
      n = n.to_int
      return outdent(-n) if n < 0
      gsub(/^/, " "*n)

Join all the lines of the string together, and compress spaces. The resulting string will have no surrounding whitespace.

  text = %{
    Once upon a time,
         Little Red Riding Hood ...


  text.join   # -> "Once upon a time, Little Red Riding Hood ..."


# File lib/extensions/string.rb, line 312
    def join
      gsub(/([ \t]*\n[ \t]*)+/, ' ').strip

Returns a line or lines from the string. args can be a single integer, two integers or a range, as per Array#slice. The return value is a single String (a single line), an array of Strings (multiple lines) or nil (out of bounds). Note that lines themselves do not contain a trailing newline character; that is metadata. Indexes out of bounds are ignored.

  data = " one \n two \n three \n four \n five \n"
  data.line(1)              # -> " two "
  data.line(0,1)            # -> [" one "]
  data.line(3..9)           # -> [" four ", " five "]
  data.line(9)              # -> nil


# File lib/extensions/string.rb, line 260
    def line(*args)
    rescue TypeError
      raise TypeError,
        "String#line(*args): args must be one Integer, two Integers or a Range"
    rescue ArgumentError
      raise ArgumentError,
        "String#line(*args): args must be one Integer, two Integers or a Range"

Outdents the string n spaces. Initial tabs will cause problems and cause a warning to be emitted (if warnings are on). Relative indendation is always preserved. Once the block hits the beginning of the line, that’s it. In the following example, . represents space from the beginning of the line.

  str = %{




# File lib/extensions/string.rb, line 99
    def outdent(n)
      n = n.to_int
      return indent(-n) if n < 0
      tabto(leftmost_indent - n)

Returns true iff this string starts with str.

   "Hello, world".starts_with?("He")         # -> true
   "Hello, world".starts_with?("Green")      # -> false


# File lib/extensions/string.rb, line 219
    def starts_with?(str)
      str = str.to_str
      head = self[0, str.length]
      head == str

Tabs all lines in the string to column n. That is, relative indentation is not preserved.


# File lib/extensions/string.rb, line 147
    def taballto(n)
      n = n.to_int
      n = 0 if n < 0
      gsub(/^[ \t]*/, " "*n)

Move the string to the nth column. Relative indentation is preserved. Column indices begin at 0, so the result is that the leftmost character of the string has n spaces before it.


  "xyz".tabto(0)           # -> "xyz"
  "xyz".tabto(1)           # -> " xyz"
  "xyz".tabto(2)           # -> "  xyz"
  "   xyz".tabto(1)        # -> " xyz"

  str = <<EOF
      Hello, my name
    is Gerald.
  str.tabto(5) == <<EOF    # -> true
         Hello, my name
       is Gerald.


# File lib/extensions/string.rb, line 130
    def tabto(n)
      n = n.to_int
      n = 0 if n < 0
      find = " " * leftmost_indent()
      replace = " " * (n)
      gsub(/^#{find}/, replace)

Trims a string:

  • removes one initial blank line
  • removes trailing spaces on each line
  • if margin is given, removes initial spaces up to and including the margin on each line, plus one space

This is designed specifically for working with inline documents. Here-documents are great, except they tend to go against the indentation of your code. This method allows a convenient way of using %{}-style documents. For instance:

  USAGE = %{
    | usage: prog [-o dir] -h file...
    |   where
    |     -o dir         outputs to DIR
    |     -h             prints this message

  # USAGE == "usage: prog [-o dir] -h file...\n  where"...
  # (note single space to right of margin is deleted)

Note carefully that if no margin string is given, then there is no clipping at the beginning of each line and your string will remain indented. You can use tabto(0) to align it with the left of screen (while preserving relative indentation).

  USAGE = %{
    usage: prog [-o dir] -h file...
        -o dir         outputs to DIR
        -h             prints this message

  # USAGE == (same as last example)


# File lib/extensions/string.rb, line 194
    def trim(margin=nil)
      s = self.dup
      # Remove initial blank line.
      s.sub!(/\A[ \t]*\n/, "")
      # Get rid of the margin, if it's specified.
      unless margin.nil?
        margin_re = Regexp.escape(margin || "")
        margin_re = /^[ \t]*#{margin_re} ?/
        s.gsub!(margin_re, "")
      # Remove trailing whitespace on each line
      s.gsub!(/[ \t]+$/, "")