class String
Experimental RBS support (using type sampling data from the type_fusion
project).
# sig/active_support/core_ext/object/blank.rbs class String def as_json: (?Hash? options) -> String def blank?: () -> bool def camelize: (?Symbol first_letter) -> String def constantize: () -> (Class | Module) def dasherize: () -> String def demodulize: () -> String def first: (?Integer limit) -> String def from: (Integer position) -> String def html_safe: () -> ActiveSupport::SafeBuffer def humanize: (capitalize: true, keep_id_suffix: false) -> String def last: (?Integer limit) -> String def parameterize: (separator: String, preserve_case: false, locale: nil) -> String def pluralize: (?(Symbol | nil | Integer) count, ?Symbol locale) -> String def singularize: (?Symbol locale) -> String def truncate: (Integer truncate_at, ?Hash options) -> String def underscore: () -> String end
def acts_like_string?
def acts_like_string? true end
def as_json(options = nil) # :nodoc:
Experimental RBS support (using type sampling data from the type_fusion
project).
def as_json: (?(nil | | prefixes | String | template | String | layout | Proc) options) -> String
This signature was generated using 2354 samples from 3 applications.
def as_json(options = nil) # :nodoc: self end
def at(position)
str.at("lo") # => "lo"
str.at(/ol/) # => nil
str.at(/lo/) # => "lo"
str = "hello"
the string. In both cases, +nil+ is returned if there is no match.
If a String is given, that given string is returned if it occurs in
If a Regexp is given, the matching portion of the string is returned.
str.at(5..-1) # => ""
str.at(5) # => nil
str.at(-2..-1) # => "lo"
str.at(-2) # => "l"
str.at(1..3) # => "ell"
str.at(0) # => "h"
str = "hello"
the beginning of the range is greater than the end of the string.
if the initial offset falls outside the string. Returns an empty string if
offset is negative, it is counted from the end of the string. Returns +nil+
characters at offsets given by the range is returned. In both cases, if an
position 1, and so on. If a range is supplied, a substring containing
position. The first character of the string is at position 0, the next at
If you pass a single integer, returns a substring of one character at that
def at(position) self[position] end
def blank?
Experimental RBS support (using type sampling data from the type_fusion
project).
def blank?: () -> bool
This signature was generated using 526 samples from 3 applications.
-
(true, false)
-
def blank? # The regexp that matches blank strings is expensive. For the case of empty # strings we can speed up this method (~3.5x) with an empty? call. The # penalty for the rest of strings is marginal. empty? || begin BLANK_RE.match?(self) rescue Encoding::CompatibilityError ENCODED_BLANKS[self.encoding].match?(self) end end
def camelize(first_letter = :upper)
Experimental RBS support (using type sampling data from the type_fusion
project).
def camelize: (?Symbol first_letter) -> String
This signature was generated using 13 samples from 1 application.
'active_record/errors'.camelize(:lower) # => "activeRecord::Errors"
'active_record/errors'.camelize # => "ActiveRecord::Errors"
'active_record'.camelize(:lower) # => "activeRecord"
'active_record'.camelize # => "ActiveRecord"
+camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
is set to :lower then camelize produces lowerCamelCase.
By default, +camelize+ converts strings to UpperCamelCase. If the argument to camelize
def camelize(first_letter = :upper) case first_letter when :upper ActiveSupport::Inflector.camelize(self, true) when :lower ActiveSupport::Inflector.camelize(self, false) else raise ArgumentError, "Invalid option, use either :upper or :lower." end end
def classify
'posts'.classify # => "Post"
'ham_and_eggs'.classify # => "HamAndEgg"
follow +classify+ with +constantize+.)
Note that this returns a string and not a class. (To convert to an actual class
Creates a class name from a plural table name like Rails does for table names to models.
def classify ActiveSupport::Inflector.classify(self) end
def constantize
Experimental RBS support (using type sampling data from the type_fusion
project).
def constantize: () -> (Class | Module)
This signature was generated using 6 samples from 2 applications.
'blargle'.constantize # => NameError: wrong constant name blargle
'Class'.constantize # => Class
'Module'.constantize # => Module
or is not initialized.
in the string. It raises a NameError when the name is not in CamelCase
+constantize+ tries to find a declared constant with the name specified
def constantize ActiveSupport::Inflector.constantize(self) end
def dasherize
Experimental RBS support (using type sampling data from the type_fusion
project).
def dasherize: () -> String
This signature was generated using 39 samples from 2 applications.
'puni_puni'.dasherize # => "puni-puni"
Replaces underscores with dashes in the string.
def dasherize ActiveSupport::Inflector.dasherize(self) end
def deconstantize
See ActiveSupport::Inflector.deconstantize.
''.deconstantize # => ""
'::String'.deconstantize # => ""
'String'.deconstantize # => ""
'::Net::HTTP'.deconstantize # => "::Net"
'Net::HTTP'.deconstantize # => "Net"
Removes the rightmost segment from the constant expression in the string.
def deconstantize ActiveSupport::Inflector.deconstantize(self) end
def demodulize
Experimental RBS support (using type sampling data from the type_fusion
project).
def demodulize: () -> String
This signature was generated using 6 samples from 1 application.
See ActiveSupport::Inflector.demodulize.
''.demodulize # => ''
'::Inflections'.demodulize # => "Inflections"
'Inflections'.demodulize # => "Inflections"
'ActiveSupport::Inflector::Inflections'.demodulize # => "Inflections"
Removes the module part from the constant expression in the string.
def demodulize ActiveSupport::Inflector.demodulize(self) end
def exclude?(string)
"hello".exclude? "ol" # => true
"hello".exclude? "lo" # => false
does not include the other string.
The inverse of String#include?. Returns true if the string
def exclude?(string) !include?(string) end
def first(limit = 1)
Experimental RBS support (using type sampling data from the type_fusion
project).
def first: (?Integer limit) -> String
This signature was generated using 1 sample from 1 application.
str.first(0) # => ""
str.first(2) # => "he"
str.first(1) # => "h"
str.first # => "h"
str = "hello"
given limit is greater than or equal to the string length, returns a copy of self.
from the beginning of the string until it reaches the limit value. If the
Returns the first character. If a limit is supplied, returns a substring
def first(limit = 1) self[0, limit] || raise(ArgumentError, "negative limit") end
def foreign_key(separate_class_name_and_id_with_underscore = true)
'Admin::Post'.foreign_key # => "post_id"
'Message'.foreign_key(false) # => "messageid"
'Message'.foreign_key # => "message_id"
the method should put '_' between the name and 'id'.
+separate_class_name_and_id_with_underscore+ sets whether
Creates a foreign key name from a class name.
def foreign_key(separate_class_name_and_id_with_underscore = true) ActiveSupport::Inflector.foreign_key(self, separate_class_name_and_id_with_underscore) end
def from(position)
Experimental RBS support (using type sampling data from the type_fusion
project).
def from: (Integer position) -> String
This signature was generated using 13 samples from 2 applications.
str.from(0).to(-1) # => "hello"
str = "hello"
You can mix it with +to+ method and do fun things like:
str.from(-2) # => "lo"
str.from(3) # => "lo"
str.from(0) # => "hello"
str = "hello"
If the position is negative, it is counted from the end of the string.
Returns a substring from the given position to the end of the string.
def from(position) self[position, length] end
def html_safe
Experimental RBS support (using type sampling data from the type_fusion
project).
def html_safe: () -> ActiveSupport::SafeBuffer
This signature was generated using 137 samples from 2 applications.
+raw+ helper in views. It is recommended that you use +sanitize+ instead of
string contains no malicious content. This method is equivalent to the
additional escaping performed. It is your responsibility to ensure that the
Marks a string as trusted safe. It will be inserted into HTML with no
def html_safe ActiveSupport::SafeBuffer.new(self) end
def humanize(capitalize: true, keep_id_suffix: false)
Experimental RBS support (using type sampling data from the type_fusion
project).
def humanize: (capitalize: true, keep_id_suffix: false) -> String
This signature was generated using 8 samples from 2 applications.
'author_id'.humanize(keep_id_suffix: true) # => "Author id"
'_id'.humanize # => "Id"
'author_id'.humanize(capitalize: false) # => "author"
'author_id'.humanize # => "Author"
'employee_salary'.humanize # => "Employee salary"
By default, this parameter is false.
optional parameter +keep_id_suffix+ to true.
The trailing '_id' can be kept and capitalized by setting the
By default, this parameter is true.
optional parameter +capitalize+ to false.
The capitalization of the first word can be turned off by setting the
Like +titleize+, this is meant for creating pretty output.
trailing '_id' if present.
Capitalizes the first word, turns underscores into spaces, and (by default)strips a
def humanize(capitalize: true, keep_id_suffix: false) ActiveSupport::Inflector.humanize(self, capitalize: capitalize, keep_id_suffix: keep_id_suffix) end
def in_time_zone(zone = ::Time.zone)
Converts String to a TimeWithZone in the current zone if Time.zone or Time.zone_default
def in_time_zone(zone = ::Time.zone) if zone ::Time.find_zone!(zone).parse(self) else to_time end end
def indent(amount, indent_string = nil, indent_empty_lines = false)
"foo\n\nbar".indent(2, nil, true) # => " foo\n \n bar"
"foo\n\nbar".indent(2) # => " foo\n\n bar"
empty lines should be indented. Default is false.
The third argument, +indent_empty_lines+, is a flag that says whether
While +indent_string+ is typically one space or tab, it may be any string.
"foo".indent(2, "\t") # => "\t\tfoo"
"foo\n\t\tbar".indent(2) # => "\t\tfoo\n\t\t\t\tbar"
" foo".indent(2) # => " foo"
none.
peeking at the first indented line, and fallback to a space if there is
use. The default is +nil+, which tells the method to make a guess by
The second argument, +indent_string+, specifies which indent string to
end
some_code
def some_method
# =>
EOS
end
some_code
def some_method
<
Indents the lines in the receiver:
def indent(amount, indent_string = nil, indent_empty_lines = false) dup.tap { |_| _.indent!(amount, indent_string, indent_empty_lines) } end
def indent!(amount, indent_string = nil, indent_empty_lines = false)
Same as +indent+, except it indents the receiver in-place.
def indent!(amount, indent_string = nil, indent_empty_lines = false) indent_string = indent_string || self[/^[ \t]/] || " " re = indent_empty_lines ? /^/ : /^(?!$)/ gsub!(re, indent_string * amount) end
def inquiry
env.production? # => true
env = 'production'.inquiry
which gives you a prettier way to test for equality.
Wraps the current string in the ActiveSupport::StringInquirer class,
def inquiry ActiveSupport::StringInquirer.new(self) end
def is_utf8?
utf_8_str.is_utf8? # => true
iso_str = "some string".encode "ISO-8859-1"
utf_8_str = "some string".encode "UTF-8"
Returns +true+ if string has utf_8 encoding.
def is_utf8? case encoding when Encoding::UTF_8, Encoding::US_ASCII valid_encoding? when Encoding::ASCII_8BIT dup.force_encoding(Encoding::UTF_8).valid_encoding? else false end end
def last(limit = 1)
Experimental RBS support (using type sampling data from the type_fusion
project).
def last: (?Integer limit) -> String
This signature was generated using 43 samples from 2 applications.
str.last(0) # => ""
str.last(2) # => "lo"
str.last(1) # => "o"
str.last # => "o"
str = "hello"
the given limit is greater than or equal to the string length, returns a copy of self.
from the end of the string until it reaches the limit value (counting backwards). If
Returns the last character of the string. If a limit is supplied, returns a substring
def last(limit = 1) self[[length - limit, 0].max, limit] || raise(ArgumentError, "negative limit") end
def mb_chars
For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars. For
object. Interoperability problems can be resolved easily with a +to_s+ call.
String and Char work like expected. The bang! methods change the internal string representation in the Chars
The Chars object tries to be as interchangeable with String objects as possible: sorting and comparing between
== Interoperability and configuration
name.mb_chars.reverse.length # => 12
method chaining on the result of any of these methods.
All the methods on the Chars proxy which normally return a string will return a Chars object. This allows
== Method chaining
=> "LJ"
>> "lj".upcase
NOTE: Ruby 2.4 and later support native Unicode case mappings:
=> "LJ"
>> "lj".mb_chars.upcase.to_s
class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsulated string.
encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy
It creates and returns an instance of the ActiveSupport::Multibyte::Chars class which
+mb_chars+ is a multibyte safe proxy for string methods.
== Multibyte proxy
def mb_chars ActiveSupport::Multibyte.proxy_class.new(self) end
def parameterize(separator: "-", preserve_case: false, locale: nil)
Experimental RBS support (using type sampling data from the type_fusion
project).
def parameterize: (separator: String, preserve_case: false, locale: nil) -> String
This signature was generated using 2 samples from 1 application.
# => Donald E. Knuth
<%= link_to(@person.name, person_path) %>
# => #
@person = Person.find(1)
end
end
"#{id}-#{name.parameterize(preserve_case: true)}"
def to_param
class Person
To preserve the case of the characters in a string, use the +preserve_case+ argument.
# => Donald E. Knuth
<%= link_to(@person.name, person_path) %>
# => #
@person = Person.find(1)
end
end
"#{id}-#{name.parameterize}"
def to_param
class Person
the configured I18n.locale.
By default, this parameter is set to nil and it will use
the word will be parameterized as a word of that language.
If the optional parameter +locale+ is specified,
Replaces special characters in a string so that it may be used as part of a 'pretty' URL.
def parameterize(separator: "-", preserve_case: false, locale: nil) ActiveSupport::Inflector.parameterize(self, separator: separator, preserve_case: preserve_case, locale: locale) end
def pluralize(count = nil, locale = :en)
Experimental RBS support (using type sampling data from the type_fusion
project).
def pluralize: (?(Symbol | nil | Integer) count, ?Symbol locale) -> String
This signature was generated using 11 samples from 2 applications.
'ley'.pluralize(1, :es) # => "ley"
'ley'.pluralize(:es) # => "leyes"
'apple'.pluralize(2) # => "apples"
'apple'.pluralize(1) # => "apple"
'CamelOctopus'.pluralize # => "CamelOctopi"
'the blue mailman'.pluralize # => "the blue mailmen"
'words'.pluralize # => "words"
'sheep'.pluralize # => "sheep"
'octopus'.pluralize # => "octopi"
'post'.pluralize # => "posts"
You must define your own inflection rules for languages other than English.
By default, this parameter is set to :en.
the word will be pluralized as a word of that language.
If the optional parameter +locale+ is specified,
For any other value of +count+ the plural will be returned.
the singular form will be returned if count == 1.
If the optional parameter +count+ is specified,
Returns the plural form of the word in the string.
def pluralize(count = nil, locale = :en) locale = count if count.is_a?(Symbol) if count == 1 dup else ActiveSupport::Inflector.pluralize(self, locale) end end
def remove(*patterns)
str.remove(" test", /bar/) # => "foo "
str.remove(" test") # => "foo bar"
str = "foo bar test"
Returns a new string with all occurrences of the patterns removed.
def remove(*patterns) dup.remove!(*patterns) end
def remove!(*patterns)
str.remove!(" test", /bar/) # => "foo "
str = "foo bar test"
Alters the string by removing all occurrences of the patterns.
def remove!(*patterns) patterns.each do |pattern| gsub! pattern, "" end self end
def safe_constantize
'blargle'.safe_constantize # => nil
'Class'.safe_constantize # => Class
'Module'.safe_constantize # => Module
or is not initialized.
in the string. It returns +nil+ when the name is not in CamelCase
+safe_constantize+ tries to find a declared constant with the name specified
def safe_constantize ActiveSupport::Inflector.safe_constantize(self) end
def singularize(locale = :en)
Experimental RBS support (using type sampling data from the type_fusion
project).
def singularize: (?Symbol locale) -> String
This signature was generated using 72 samples from 2 applications.
'leyes'.singularize(:es) # => "ley"
'CamelOctopi'.singularize # => "CamelOctopus"
'the blue mailmen'.singularize # => "the blue mailman"
'word'.singularize # => "word"
'sheep'.singularize # => "sheep"
'octopi'.singularize # => "octopus"
'posts'.singularize # => "post"
You must define your own inflection rules for languages other than English.
By default, this parameter is set to :en.
the word will be singularized as a word of that language.
If the optional parameter +locale+ is specified,
The reverse of +pluralize+, returns the singular form of a word in a string.
def singularize(locale = :en) ActiveSupport::Inflector.singularize(self, locale) end
def squish
string }.squish # => "Multi-line string"
%{ Multi-line
Note that it handles both ASCII and Unicode whitespace.
groups into one space each.
the string, and then changing remaining consecutive whitespace
Returns the string, first removing all whitespace on both ends of
def squish dup.squish! end
def squish!
str.squish! # => "foo bar boo"
str = " foo bar \n \t boo"
Performs a destructive squish. See String#squish.
def squish! gsub!(/[[:space:]]+/, " ") strip! self end
def strip_heredoc
Technically, it looks for the least indented non-empty line
the user would see the usage message aligned against the left margin.
end
USAGE
...
-h This message
Supported options are:
This command does such and such.
puts <<-USAGE.strip_heredoc
if options[:usage]
For example in
Strips indentation in heredocs.
def strip_heredoc gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, "").tap do |stripped| stripped.freeze if frozen? end end
def tableize
'fancyCategory'.tableize # => "fancy_categories"
'ham_and_egg'.tableize # => "ham_and_eggs"
'RawScaledScorer'.tableize # => "raw_scaled_scorers"
uses the +pluralize+ method on the last word in the string.
Creates the name of a table like Rails does for models to table names. This method
def tableize ActiveSupport::Inflector.tableize(self) end
def titleize(keep_id_suffix: false)
'string_ending_with_id'.titleize(keep_id_suffix: true) # => "String Ending With Id"
'x-men: the last stand'.titleize # => "X Men: The Last Stand"
'man from the boondocks'.titleize # => "Man From The Boondocks"
By default, this parameter is false.
optional parameter +keep_id_suffix+ to true.
The trailing '_id','Id'.. can be kept and capitalized by setting the
used in the Rails internals.
a nicer looking title. +titleize+ is meant for creating pretty output. It is not
Capitalizes all the words and replaces some characters in the string to create
def titleize(keep_id_suffix: false) ActiveSupport::Inflector.titleize(self, keep_id_suffix: keep_id_suffix) end
def to(position)
str.from(0).to(-1) # => "hello"
str = "hello"
You can mix it with +from+ method and do fun things like:
str.to(-2) # => "hell"
str.to(3) # => "hell"
str.to(0) # => "h"
str = "hello"
If the position is negative, it is counted from the end of the string.
Returns a substring from the beginning of the string to the given position.
def to(position) position += size if position < 0 self[0, position + 1] || +"" end
def to_date
"2012-12-13".to_date # => Thu, 13 Dec 2012
"01/01/2012".to_date # => Sun, 01 Jan 2012
"1-1-2012".to_date # => Sun, 01 Jan 2012
Converts a string to a Date value.
def to_date ::Date.parse(self, false) unless blank? end
def to_datetime
"2012-12-13 12:50".to_datetime # => Thu, 13 Dec 2012 12:50:00 +0000
"01/01/2012 23:59:59".to_datetime # => Sun, 01 Jan 2012 23:59:59 +0000
"1-1-2012".to_datetime # => Sun, 01 Jan 2012 00:00:00 +0000
Converts a string to a DateTime value.
def to_datetime ::DateTime.parse(self, false) unless blank? end
def to_time(form = :local)
"12/13/2012".to_time # => ArgumentError: argument out of range
"2012-12-13T06:12".to_time(:utc) # => 2012-12-13 06:12:00 UTC
"2012-12-13T06:12".to_time # => 2012-12-13 06:12:00 +0100
"2012-12-13 06:12".to_time # => 2012-12-13 06:12:00 +0100
"06:12".to_time # => 2012-12-13 06:12:00 +0100
"13-12-2012".to_time # => 2012-12-13 00:00:00 +0100
the time part is missing then it is assumed to be 00:00:00.
If the date part is missing then the current date is used and if
If +form+ is +:local+, then the time is in the system timezone.
The time is parsed using Time.parse method.
The +form+ can be either +:utc+ or +:local+ (default +:local+).
Converts a string to a Time value.
def to_time(form = :local) parts = Date._parse(self, false) used_keys = %i(year mon mday hour min sec sec_fraction offset) return if (parts.keys & used_keys).empty? now = Time.now time = Time.new( parts.fetch(:year, now.year), parts.fetch(:mon, now.month), parts.fetch(:mday, now.day), parts.fetch(:hour, 0), parts.fetch(:min, 0), parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0), parts.fetch(:offset, form == :utc ? 0 : nil) ) form == :utc ? time.utc : time.to_time end
def truncate(truncate_at, options = {})
Experimental RBS support (using type sampling data from the type_fusion
project).
def truncate: (Integer truncate_at, ?( | length | Integer | separator | String | omission | String | escape | TrueClass) options) -> String
This signature was generated using 8 samples from 1 application.
'And they found that many people were sleeping better.'.truncate(25, omission: '... (continued)')
for a total length not exceeding length:
The last characters will be replaced with the :omission string (defaults to "...")
# => "Once upon a time in a..."
'Once upon a time in a world far far away'.truncate(27, separator: /\s/)
# => "Once upon a time in a..."
'Once upon a time in a world far far away'.truncate(27, separator: ' ')
Pass a string or regexp :separator to truncate +text+ at a natural break:
# => "Once upon a time in a wo..."
'Once upon a time in a world far far away'.truncate(27)
Truncates a given +text+ after a given length if +text+ is longer than length:
def truncate(truncate_at, options = {}) return dup unless length > truncate_at omission = options[:omission] || "..." length_with_room_for_omission = truncate_at - omission.length stop = \ if options[:separator] rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission else length_with_room_for_omission end +"#{self[0, stop]}#{omission}" end
def truncate_bytes(truncate_at, omission: "…")
The truncated text ends with the :omission string, defaulting
=> "🔪🔪🔪🔪…"
>> "🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪".truncate_bytes(20)
=> 80
>> "🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪".bytesize
=> 20
>> "🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪".size
characters.
grapheme clusters ("perceptual characters") by truncating at combining
breaking string encoding by splitting multibyte characters or breaking
Truncates +text+ to at most bytesize bytes in length without
def truncate_bytes(truncate_at, omission: "…") omission ||= "" case when bytesize <= truncate_at dup when omission.bytesize > truncate_at raise ArgumentError, "Omission #{omission.inspect} is #{omission.bytesize}, larger than the truncation length of #{truncate_at} bytes" when omission.bytesize == truncate_at omission.dup else self.class.new.tap do |cut| cut_at = truncate_at - omission.bytesize each_grapheme_cluster do |grapheme| if cut.bytesize + grapheme.bytesize <= cut_at cut << grapheme else break end end cut << omission end end end
def truncate_words(words_count, options = {})
'And they found that many people were sleeping better.'.truncate_words(5, omission: '... (continued)')
The last characters will be replaced with the :omission string (defaults to "..."):
# => "Once
upon
a
time
in..."
'Once
upon
a
time
in
a
world'.truncate_words(5, separator: '
')
Pass a string or regexp :separator to specify a different separator of words:
# => "Once upon a time..."
'Once upon a time in a world far far away'.truncate_words(4)
Truncates a given +text+ after a given number of words (words_count):
def truncate_words(words_count, options = {}) sep = options[:separator] || /\s+/ sep = Regexp.escape(sep.to_s) unless Regexp === sep if self =~ /\A((?>.+?#{sep}){#{words_count - 1}}.+?)#{sep}.*/m $1 + (options[:omission] || "...") else dup end end
def underscore
Experimental RBS support (using type sampling data from the type_fusion
project).
def underscore: () -> String
This signature was generated using 9 samples from 2 applications.
'ActiveModel::Errors'.underscore # => "active_model/errors"
'ActiveModel'.underscore # => "active_model"
+underscore+ will also change '::' to '/' to convert namespaces to paths.
The reverse of +camelize+. Makes an underscored, lowercase form from the expression in the string.
def underscore ActiveSupport::Inflector.underscore(self) end
def upcase_first
''.upcase_first # => ""
'w'.upcase_first # => "W"
'what a Lovely Day'.upcase_first # => "What a Lovely Day"
Converts just the first character to uppercase.
def upcase_first ActiveSupport::Inflector.upcase_first(self) end