Class | String |
In: |
lib/extensions/string.rb
|
Parent: | Object |
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 else n = [self.size, other.size].min (0..n).each do |i| return i unless self[i] == other[i] end end end
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 end
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 while str.gsub!(/^([^\t\n]*)(\t+)/) { |f| val = ( n * $2.size - ($1.size % n) ) $1 << (' ' * val) } end str end
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) end
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 end
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) self.split(/\n/).slice(*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" end
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 = %{ ..One ....Two }.outdent(4)
is
One ..Two
# File lib/extensions/string.rb, line 99 def outdent(n) n = n.to_int return indent(-n) if n < 0 tabto(leftmost_indent - n) end
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 end
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) end
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.
Examples:
"xyz".tabto(0) # -> "xyz" "xyz".tabto(1) # -> " xyz" "xyz".tabto(2) # -> " xyz" " xyz".tabto(1) # -> " xyz" str = <<EOF Hello, my name is Gerald. EOF str.tabto(5) == <<EOF # -> true Hello, my name is Gerald. EOF
# 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) end
Trims a string:
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 }.trim("|") # 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... where -o dir outputs to DIR -h prints this message }.trim.tabto(0) # 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, "") end # Remove trailing whitespace on each line s.gsub!(/[ \t]+$/, "") s end
Returns the size of the smallest indent of any line in the string. Emits a warning if tabs are found, and if $VERBOSE is on. You can use expand_tabs to avoid this. This method is primarily intended for use by tabto and is not likely to be all that useful in its own right.
# File lib/extensions/string.rb, line 21 def leftmost_indent tabs_found = false scan(/^([ \t]*)\S/).flatten.map { |ws| tabs_found = true if ws =~ /\t/ ws.size }.compact.min ensure if tabs_found and $VERBOSE $stderr.puts %{ String#leftmost_indent: warning: tabs treated as spaces (value: #{self.inspect[0..30]}...") }.strip end end