module Fusu::String::Methods
Constants
- ACRONYM_REGEX
Public Instance Methods
Converts strings to UpperCamelCase. If the uppercase_first_letter
parameter is set to false, then produces lowerCamelCase.
Also converts '/' to '::' which is useful for converting paths to namespaces.
camelize('active_model') # => "ActiveModel" camelize('active_model', false) # => "activeModel" camelize('active_model/errors') # => "ActiveModel::Errors" camelize('active_model/errors', false) # => "activeModel::Errors"
As a rule of thumb you can think of camelize
as the inverse of underscore
, though there are cases where that does not hold:
camelize(underscore('SSLError')) # => "SslError"
# File lib/fusu/string/methods.rb, line 33 def camelize(term, uppercase_first_letter = true) string = term.to_s if uppercase_first_letter string = string.sub(/^[a-z\d]*/) { |match| match.capitalize } else string = string.sub(/^(?:#{ACRONYM_REGEX}(?=\b|[A-Z_])|\w)/) { |match| match.downcase } end string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{$2.capitalize}" } string.gsub!("/".freeze, "::".freeze) string end
Tries to find a constant with the name specified in the argument string.
constantize('Module') # => Module constantize('Foo::Bar') # => Foo::Bar
The name is assumed to be the one of a top-level constant, no matter whether it starts with “::” or not. No lexical context is taken into account:
C = 'outside' module M C = 'inside' C # => 'inside' constantize('C') # => 'outside', same as ::C end
NameError is raised when the name is not in CamelCase or the constant is unknown.
# File lib/fusu/string/methods.rb, line 211 def constantize(camel_cased_word) names = camel_cased_word.split("::".freeze) # Trigger a built-in NameError exception including the ill-formed constant in the message. Object.const_get(camel_cased_word) if names.empty? # Remove the first blank element in case of '::ClassName' notation. names.shift if names.size > 1 && names.first.empty? names.inject(Object) do |constant, name| if constant == Object constant.const_get(name) else candidate = constant.const_get(name) next candidate if constant.const_defined?(name, false) next candidate unless Object.const_defined?(name) # Go down the ancestors to check if it is owned directly. The check # stops when we reach Object or the end of ancestors tree. constant = constant.ancestors.inject(constant) do |const, ancestor| break const if ancestor == Object break ancestor if ancestor.const_defined?(name, false) const end # owner is in Object, so raise constant.const_get(name, false) end end end
Replaces underscores with dashes in the string.
dasherize('puni_puni') # => "puni-puni"
# File lib/fusu/string/methods.rb, line 148 def dasherize(underscored_word) underscored_word.tr("_".freeze, "-".freeze) end
Removes the rightmost segment from the constant expression in the string.
deconstantize('Net::HTTP') # => "Net" deconstantize('::Net::HTTP') # => "::Net" deconstantize('String') # => "" deconstantize('::String') # => "" deconstantize('') # => ""
See also demodulize
.
# File lib/fusu/string/methods.rb, line 178 def deconstantize(path) path.to_s[0, path.rindex("::") || 0] # implementation based on the one in facets' Module#spacename end
Removes the module part from the expression in the string.
demodulize('ActiveSupport::Inflector::Inflections') # => "Inflections" demodulize('Inflections') # => "Inflections" demodulize('::Inflections') # => "Inflections" demodulize('') # => ""
See also deconstantize
.
# File lib/fusu/string/methods.rb, line 160 def demodulize(path) path = path.to_s if i = path.rindex("::") path[(i + 2)..-1] else path end end
Creates a foreign key name from a class name. separate_class_name_and_id_with_underscore
sets whether the method should put '_' between the name and 'id'.
foreign_key('Message') # => "message_id" foreign_key('Message', false) # => "messageid" foreign_key('Admin::Post') # => "post_id"
# File lib/fusu/string/methods.rb, line 189 def foreign_key(class_name, separate_class_name_and_id_with_underscore = true) underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id") end
Tweaks an attribute name for display to end users.
Specifically, performs these transformations:
-
Applies human inflection rules to the argument.
-
Deletes leading underscores, if any.
-
Removes a “_id” suffix if present.
-
Replaces underscores with spaces, if any.
-
Downcases all words except acronyms.
-
Capitalizes the first word.
The capitalization of the first word can be turned off by setting the :capitalize
option to false (default is true).
The trailing '_id' can be kept and capitalized by setting the optional parameter keep_id_suffix
to true (default is false).
humanize('employee_salary') # => "Employee salary" humanize('author_id') # => "Author" humanize('author_id', capitalize: false) # => "author" humanize('_id') # => "Id" humanize('author_id', keep_id_suffix: true) # => "Author Id"
If “SSL” was defined to be an acronym:
humanize('ssl_error') # => "SSL error"
# File lib/fusu/string/methods.rb, line 102 def humanize(lower_case_and_underscored_word, capitalize: true, keep_id_suffix: false) result = lower_case_and_underscored_word.to_s.dup # inflections.humans.each { |(rule, replacement)| break if result.sub!(rule, replacement) } result.sub!(/\A_+/, "".freeze) unless keep_id_suffix result.sub!(/_id\z/, "".freeze) end result.tr!("_".freeze, " ".freeze) result.gsub!(/([a-z\d]*)/i) do |match| "#{match.downcase}" end if capitalize result.sub!(/\A\w/) { |match| match.upcase } end result end
Returns the suffix that should be added to a number to denote the position in an ordered sequence such as 1st, 2nd, 3rd, 4th.
ordinal(1) # => "st" ordinal(2) # => "nd" ordinal(1002) # => "nd" ordinal(1003) # => "rd" ordinal(-11) # => "th" ordinal(-1021) # => "st"
# File lib/fusu/string/methods.rb, line 282 def ordinal(number) abs_number = number.to_i.abs if (11..13).include?(abs_number % 100) "th" else case abs_number % 10 when 1; "st" when 2; "nd" when 3; "rd" else "th" end end end
Turns a number into an ordinal string used to denote the position in an ordered sequence such as 1st, 2nd, 3rd, 4th.
ordinalize(1) # => "1st" ordinalize(2) # => "2nd" ordinalize(1002) # => "1002nd" ordinalize(1003) # => "1003rd" ordinalize(-11) # => "-11th" ordinalize(-1021) # => "-1021st"
# File lib/fusu/string/methods.rb, line 306 def ordinalize(number) "#{number}#{ordinal(number)}" end
Tries to find a constant with the name specified in the argument string.
safe_constantize('Module') # => Module safe_constantize('Foo::Bar') # => Foo::Bar
The name is assumed to be the one of a top-level constant, no matter whether it starts with “::” or not. No lexical context is taken into account:
C = 'outside' module M C = 'inside' C # => 'inside' safe_constantize('C') # => 'outside', same as ::C end
nil
is returned when the name is not in CamelCase or the constant (or part of it) is unknown.
safe_constantize('blargle') # => nil safe_constantize('UnknownModule') # => nil safe_constantize('UnknownModule::Foo::Bar') # => nil
# File lib/fusu/string/methods.rb, line 264 def safe_constantize(camel_cased_word) constantize(camel_cased_word) rescue NameError => e raise if e.name && !(camel_cased_word.to_s.split("::").include?(e.name.to_s) || e.name.to_s == camel_cased_word.to_s) rescue ArgumentError => e raise unless /not missing constant #{const_regexp(camel_cased_word)}!$/.match?(e.message) end
Capitalizes all the words and replaces some characters in the string to create a nicer looking title. titleize
is meant for creating pretty output. It is not used in the Rails internals.
The trailing '_id','Id'.. can be kept and capitalized by setting the optional parameter keep_id_suffix
to true. By default, this parameter is false.
titleize
is also aliased as titlecase
.
titleize('man from the boondocks') # => "Man From The Boondocks" titleize('x-men: the last stand') # => "X Men: The Last Stand" titleize('TheManWithoutAPast') # => "The Man Without A Past" titleize('raiders_of_the_lost_ark') # => "Raiders Of The Lost Ark" titleize('string_ending_with_id', keep_id_suffix: true) # => "String Ending With Id"
# File lib/fusu/string/methods.rb, line 139 def titleize(word, keep_id_suffix: false) humanize(underscore(word), keep_id_suffix: keep_id_suffix).gsub(/\b(?<!\w['’`])[a-z]/) do |match| match.capitalize end end
Makes an underscored, lowercase form from the expression in the string.
Changes '::' to '/' to convert namespaces to paths.
underscore('ActiveModel') # => "active_model" underscore('ActiveModel::Errors') # => "active_model/errors"
As a rule of thumb you can think of underscore
as the inverse of camelize
, though there are cases where that does not hold:
camelize(underscore('SSLError')) # => "SslError"
# File lib/fusu/string/methods.rb, line 56 def underscore(camel_cased_word) return camel_cased_word unless Fusu::Regexp.match?(/[A-Z-]|::/, camel_cased_word) word = camel_cased_word.to_s.gsub("::".freeze, "/".freeze) word.gsub!(/(?:(?<=([A-Za-z\d]))|\b)(#{ACRONYM_REGEX})(?=\b|[^a-z])/) { "#{$1 && '_'.freeze }" } word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2'.freeze) word.gsub!(/([a-z\d])([A-Z])/, '\1_\2'.freeze) word.tr!("-".freeze, "_".freeze) word.downcase! word end
Converts just the first character to uppercase.
upcase_first('what a Lovely Day') # => "What a Lovely Day" upcase_first('w') # => "W" upcase_first('') # => ""
# File lib/fusu/string/methods.rb, line 72 def upcase_first(string) string.length > 0 ? string[0].upcase.concat(string[1..-1]) : "" end
Private Instance Methods
Mounts a regular expression, returned as a string to ease interpolation, that will match part by part the given constant.
const_regexp("Foo::Bar::Baz") # => "Foo(::Bar(::Baz)?)?" const_regexp("::") # => "::"
# File lib/fusu/string/methods.rb, line 317 def const_regexp(camel_cased_word) parts = camel_cased_word.split("::".freeze) return Regexp.escape(camel_cased_word) if parts.blank? last = parts.pop parts.reverse.inject(last) do |acc, part| part.empty? ? acc : "#{part}(::#{acc})?" end end