Class: Hanami::Utils::String

Inherits:
Object
  • Object
show all
Extended by:
Transproc::Composer, Transproc::Registry
Defined in:
gems/gems/hanami-utils-1.3.0/lib/hanami/utils/string.rb

Overview

String on steroids

Since:

  • 0.1.0

Direct Known Subclasses

PathPrefix

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(string) ⇒ Hanami::Utils::String

Deprecated.

Initialize the string

Parameters:

  • string (::String, Symbol)

    the value we want to initialize

Since:

  • 0.1.0

def initialize(string)
  @string = string.to_s
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args, &blk) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Override Ruby's method_missing in order to provide ::String interface

Raises:

  • (NoMethodError)

    If doesn't respond to the given method

Since:

  • 0.3.0

def method_missing(method_name, *args, &blk)
  raise NoMethodError.new(%(undefined method `#{method_name}' for "#{@string}":#{self.class})) unless respond_to?(method_name)

  s = @string.__send__(method_name, *args, &blk)
  s = self.class.new(s) if s.is_a?(::String)
  s
end

Class Method Details

.capitalize(input) ⇒ ::String

Return a capitalized version of the string

Examples:

require 'hanami/utils/string'

Hanami::Utils::String.capitalize('hanami') # => "Hanami"

Hanami::Utils::String.capitalize('hanami utils') # => "Hanami utils"

Hanami::Utils::String.capitalize('Hanami Utils') # => "Hanami utils"

Hanami::Utils::String.capitalize('hanami_utils') # => "Hanami utils"

Hanami::Utils::String.capitalize('hanami-utils') # => "Hanami utils"

Parameters:

  • input (::String)

    the input

Returns:

  • (::String)

    the transformed string

Since:

  • 1.1.0

def self.capitalize(input)
  string = ::String.new(input.to_s)
  head, *tail = underscore(string).split(CLASSIFY_SEPARATOR)

  tail.unshift(head.capitalize).join(CAPITALIZE_SEPARATOR)
end

.classify(input) ⇒ ::String

Return a CamelCase version of the string

Examples:

require 'hanami/utils/string'

Hanami::Utils::String.classify('hanami_utils') # => 'HanamiUtils'

Parameters:

  • input (::String)

    the input

Returns:

  • (::String)

    the transformed string

Since:

  • 1.1.0

def self.classify(input)
  string = ::String.new(input.to_s)
  words = underscore(string).split(CLASSIFY_WORD_SEPARATOR).map!(&:capitalize)
  delimiters = underscore(string).scan(CLASSIFY_WORD_SEPARATOR)

  delimiters.map! do |delimiter|
    delimiter == CLASSIFY_SEPARATOR ? EMPTY_STRING : NAMESPACE_SEPARATOR
  end

  words.zip(delimiters).join
end

.dasherize(input) ⇒ Object

Hanami::Utils::String.dasherize('hanami_utils') # => 'hanami-utils'

Hanami::Utils::String.dasherize('HanamiUtils') # => “hanami-utils”

Since:

  • 0.1.0

def self.dasherize(input)
  string = ::String.new(input.to_s)
  underscore(string).split(CLASSIFY_SEPARATOR).join(DASHERIZE_SEPARATOR)
end

.demodulize(input) ⇒ ::String

Return the string without the Ruby namespace of the class

Examples:

require 'hanami/utils/string'

Hanami::Utils::String.demodulize('Hanami::Utils::String') # => 'String'

Hanami::Utils::String.demodulize('String') # => 'String'

Parameters:

  • input (::String)

    the input

Returns:

  • (::String)

    the transformed string

Since:

  • 1.1.0

def self.demodulize(input)
  ::String.new(input.to_s).split(NAMESPACE_SEPARATOR).last
end

.namespace(input) ⇒ ::String

Return the top level namespace name

Examples:

require 'hanami/utils/string'

Hanami::Utils::String.namespace('Hanami::Utils::String') # => 'Hanami'

Hanami::Utils::String.namespace('String') # => 'String'

Parameters:

  • input (::String)

    the input

Returns:

  • (::String)

    the transformed string

Since:

  • 1.1.0

def self.namespace(input)
  ::String.new(input.to_s).split(NAMESPACE_SEPARATOR).first
end

.pluralize(input) ⇒ ::String

Deprecated.

Return a pluralized version of self.

Examples:

require 'hanami/utils/string'

Hanami::Utils::String.pluralize('book') # => 'books'

Parameters:

  • input (::String)

    the input

Returns:

  • (::String)

    the pluralized string.

See Also:

Since:

  • 1.1.0

def self.pluralize(input)
  string = ::String.new(input.to_s)
  Inflector.pluralize(string)
end

.rsub(input, pattern, replacement) ⇒ ::String

Replace the rightmost match of pattern with replacement

If the pattern cannot be matched, it returns the original string.

This method does NOT mutate the original string.

Examples:

require 'hanami/utils/string'

Hanami::Utils::String.rsub('authors/books/index', %r{/}, '#')
  # => 'authors/books#index'

Parameters:

  • input (::String)

    the input

  • pattern (Regexp, ::String)

    the pattern to find

  • replacement (String)

    the string to replace

Returns:

  • (::String)

    the replaced string

Since:

  • 1.1.0

def self.rsub(input, pattern, replacement)
  string = ::String.new(input.to_s)
  if i = string.rindex(pattern) # rubocop:disable Lint/AssignmentInCondition
    s = string.dup
    s[i] = replacement
    s
  else
    string
  end
end

.singularize(input) ⇒ ::String

Deprecated.

Return a singularized version of self.

Examples:

require 'hanami/utils/string'

Hanami::Utils::String.singularize('books') # => 'book'

Parameters:

  • input (::String)

    the input

Returns:

  • (::String)

    the singularized string.

See Also:

Since:

  • 1.1.0

def self.singularize(input)
  string = ::String.new(input.to_s)
  Inflector.singularize(string)
end

.titleize(input) ⇒ ::String

Return a titleized version of the string

Examples:

require 'hanami/utils/string'

Hanami::Utils::String.titleize('hanami utils') # => "Hanami Utils"

Parameters:

  • input (::String)

    the input

Returns:

  • (::String)

    the transformed string

Since:

  • 1.1.0

def self.titleize(input)
  string = ::String.new(input.to_s)
  underscore(string).split(CLASSIFY_SEPARATOR).map(&:capitalize).join(TITLEIZE_SEPARATOR)
end

.transform(input, *transformations) ⇒ ::String

Apply the given transformation(s) to input

It performs a pipeline of transformations, by applying the given functions from Hanami::Utils::String and ::String. The transformations are applied in the given order.

It doesn't mutate the input, unless you use destructive methods from ::String

rubocop:disable Metrics/AbcSize rubocop:disable Metrics/MethodLength

Examples:

Basic usage

require "hanami/utils/string"

Hanami::Utils::String.transform("hanami/utils", :underscore, :classify)
  # => "Hanami::Utils"

Hanami::Utils::String.transform("Hanami::Utils::String", [:gsub, /[aeiouy]/, "*"], :demodulize)
  # => "H*n*m*"

Hanami::Utils::String.transform("Hanami", ->(s) { s.upcase })
  # => "HANAMI"

Unkown transformation

require "hanami/utils/string"

Hanami::Utils::String.transform("Sakura", :foo)
  # => NoMethodError: undefined method `:foo' for "Sakura":String

Proc with arity not equal to 1

require "hanami/utils/string"

Hanami::Utils::String.transform("Cherry", -> { "blossom" }))
  # => ArgumentError: wrong number of arguments (given 1, expected 0)

Parameters:

  • input (::String)

    the string to be transformed

  • transformations (Array<Symbol,Proc,Array>)

    one or many transformations expressed as: * Symbol to reference a function from Hanami::Utils::String or String. * Proc an anonymous function that MUST accept one input * Array where the first element is a Symbol to reference a function from Hanami::Utils::String or String and the rest of the elements are the arguments to pass

Returns:

  • (::String)

    the result of the transformations

Raises:

  • (NoMethodError)

    if a Hanami::Utils::String and ::String don't respond to a given method name

  • (ArgumentError)

    if a Proc transformation has an arity not equal to 1

Since:

  • 1.1.0

def self.transform(input, *transformations)
  fn = @__transformations__.fetch_or_store(transformations.hash) do
    compose do |fns|
      transformations.each do |transformation, *args|
        fns << if transformation.is_a?(Proc)
                 transformation
               elsif contain?(transformation)
                 self[transformation, *args]
               elsif input.respond_to?(transformation)
                 t(:bind, input, ->(i) { i.public_send(transformation, *args) })
               else
                 raise NoMethodError.new(%(undefined method `#{transformation.inspect}' for #{input.inspect}:#{input.class}))
               end
      end
    end
  end

  fn.call(input)
end

.underscore(input) ⇒ ::String

Return a downcased and underscore separated version of the string

Revised version of ActiveSupport::Inflector.underscore implementation

Examples:

require 'hanami/utils/string'

Hanami::Utils::String.underscore('HanamiUtils') # => 'hanami_utils'

Parameters:

  • input (::String)

    the input

Returns:

  • (::String)

    the transformed string

See Also:

Since:

  • 1.1.0

def self.underscore(input)
  string = ::String.new(input.to_s)
  string.gsub!(NAMESPACE_SEPARATOR, UNDERSCORE_SEPARATOR)
  string.gsub!(NAMESPACE_SEPARATOR, UNDERSCORE_SEPARATOR)
  string.gsub!(/([A-Z\d]+)([A-Z][a-z])/, UNDERSCORE_DIVISION_TARGET)
  string.gsub!(/([a-z\d])([A-Z])/, UNDERSCORE_DIVISION_TARGET)
  string.gsub!(/[[:space:]]|\-/, UNDERSCORE_DIVISION_TARGET)
  string.downcase
end

Instance Method Details

#==(other) ⇒ TrueClass, FalseClass Also known as: eql?

Deprecated.

Equality

Returns:

  • (TrueClass, FalseClass)

Since:

  • 0.3.0

def ==(other)
  to_s == other
end

#capitalizeHanami::Utils::String

Deprecated.

Return a capitalized version of the string

Examples:

require 'hanami/utils/string'

string = Hanami::Utils::String.new 'hanami'
string.capitalize # => "Hanami"

string = Hanami::Utils::String.new 'hanami utils'
string.capitalize # => "Hanami utils"

string = Hanami::Utils::String.new 'Hanami Utils'
string.capitalize # => "Hanami utils"

string = Hanami::Utils::String.new 'hanami_utils'
string.capitalize # => "Hanami utils"

string = Hanami::Utils::String.new 'hanami-utils'
string.capitalize # => "Hanami utils"

Returns:

Since:

  • 0.5.2

def capitalize
  head, *tail = underscore.split(CLASSIFY_SEPARATOR)

  self.class.new(
    tail.unshift(head.capitalize).join(CAPITALIZE_SEPARATOR)
  )
end

#classifyHanami::Utils::String

Deprecated.

Use classify

Return a CamelCase version of the string

Examples:

require 'hanami/utils/string'

string = Hanami::Utils::String.new 'hanami_utils'
string.classify # => 'HanamiUtils'

Returns:

Since:

  • 0.1.0

def classify
  words = underscore.split(CLASSIFY_WORD_SEPARATOR).map!(&:capitalize)
  delimiters = underscore.scan(CLASSIFY_WORD_SEPARATOR)

  delimiters.map! do |delimiter|
    delimiter == CLASSIFY_SEPARATOR ? EMPTY_STRING : NAMESPACE_SEPARATOR
  end

  self.class.new words.zip(delimiters).join
end

#dasherizeHanami::Utils::String

Deprecated.

Use dasherize

Return a downcased and dash separated version of the string

Examples:

require 'hanami/utils/string'

string = Hanami::Utils::String.new 'Hanami Utils'
string.dasherize # => 'hanami-utils'

string = Hanami::Utils::String.new 'hanami_utils'
string.dasherize # => 'hanami-utils'

string = Hanami::Utils::String.new 'HanamiUtils'
string.dasherize # => "hanami-utils"

Returns:

Since:

  • 0.4.0

def dasherize
  self.class.new underscore.split(CLASSIFY_SEPARATOR).join(DASHERIZE_SEPARATOR)
end

#demodulizeHanami::Utils::String

Deprecated.

Return the string without the Ruby namespace of the class

Examples:

require 'hanami/utils/string'

string = Hanami::Utils::String.new 'Hanami::Utils::String'
string.demodulize # => 'String'

string = Hanami::Utils::String.new 'String'
string.demodulize # => 'String'

Returns:

Since:

  • 0.1.0

def demodulize
  self.class.new split(NAMESPACE_SEPARATOR).last
end

#gsub(pattern, replacement = nil, &blk) ⇒ ::String

Deprecated.

Replace the given pattern with the given replacement

Returns:

  • (::String)

See Also:

Since:

  • 0.3.0

def gsub(pattern, replacement = nil, &blk)
  if block_given?
    @string.gsub(pattern, &blk)
  else
    @string.gsub(pattern, replacement)
  end
end

#hashInteger

Deprecated.

Returns the hash of the internal string

Returns:

  • (Integer)

Since:

  • 0.3.0

def hash
  @string.hash
end

#namespaceHanami::Utils::String

Deprecated.

Use namespace

Return the top level namespace name

Examples:

require 'hanami/utils/string'

string = Hanami::Utils::String.new 'Hanami::Utils::String'
string.namespace # => 'Hanami'

string = Hanami::Utils::String.new 'String'
string.namespace # => 'String'

Returns:

Since:

  • 0.1.2

def namespace
  self.class.new split(NAMESPACE_SEPARATOR).first
end

#rsub(pattern, replacement) ⇒ Hanami::Utils::String

Deprecated.

Use rsub

Replace the rightmost match of pattern with replacement

If the pattern cannot be matched, it returns the original string.

This method does NOT mutate the original string.

Examples:

require 'hanami/utils/string'

string = Hanami::Utils::String.new('authors/books/index')
result = string.rsub(/\//, '#')

puts string
  # => #<Hanami::Utils::String:0x007fdb41233ad8 @string="authors/books/index">

puts result
  # => #<Hanami::Utils::String:0x007fdb41232ed0 @string="authors/books#index">

Parameters:

Returns:

Since:

  • 0.6.0

def rsub(pattern, replacement)
  if i = rindex(pattern) # rubocop:disable Lint/AssignmentInCondition
    s    = @string.dup
    s[i] = replacement
    self.class.new s
  else
    self
  end
end

#scan(pattern, &blk) ⇒ Array<::String>

Deprecated.

Iterate through the string, matching the pattern. Either return all those patterns, or pass them to the block.

Returns:

  • (Array<::String>)

See Also:

Since:

  • 0.6.0

def scan(pattern, &blk)
  @string.scan(pattern, &blk)
end

#split(pattern, limit = 0) ⇒ Array<::String>

Deprecated.

Split the string with the given pattern

Returns:

  • (Array<::String>)

See Also:

Since:

  • 0.3.0

def split(pattern, limit = 0)
  @string.split(pattern, limit)
end

#titleizeHanami::Utils::String

Deprecated.

Use titleize

Return a titleized version of the string

Examples:

require 'hanami/utils/string'

string = Hanami::Utils::String.new 'hanami utils'
string.titleize # => "Hanami Utils"

Returns:

Since:

  • 0.4.0

def titleize
  self.class.new underscore.split(CLASSIFY_SEPARATOR).map(&:capitalize).join(TITLEIZE_SEPARATOR)
end

#to_s::String Also known as: to_str

Deprecated.

Returns a string representation

Returns:

  • (::String)

Since:

  • 0.3.0

def to_s
  @string
end

#tokenize { ... } ⇒ void

Deprecated.

This method returns an undefined value.

It iterates through the tokens and calls the given block. A token is a substring wrapped by () and separated by |.

rubocop:disable Metrics/MethodLength

Examples:

require 'hanami/utils/string'

string = Hanami::Utils::String.new 'Hanami::(Utils|App)'
string.tokenize do |token|
  puts token
end

# =>
  'Hanami::Utils'
  'Hanami::App'

Yields:

  • the block that is called for each token.

Since:

  • 0.1.0

def tokenize
  if match = TOKENIZE_REGEXP.match(@string) # rubocop:disable Lint/AssignmentInCondition
    pre  = match.pre_match
    post = match.post_match
    tokens = match[1].split(TOKENIZE_SEPARATOR)
    tokens.each do |token|
      yield(self.class.new("#{pre}#{token}#{post}"))
    end
  else
    yield(self.class.new(@string))
  end

  nil
end

#underscoreHanami::Utils::String

Deprecated.

Return a downcased and underscore separated version of the string

Revised version of ActiveSupport::Inflector.underscore implementation

Examples:

require 'hanami/utils/string'

string = Hanami::Utils::String.new 'HanamiUtils'
string.underscore # => 'hanami_utils'

Returns:

See Also:

Since:

  • 0.1.0

def underscore
  new_string = gsub(NAMESPACE_SEPARATOR, UNDERSCORE_SEPARATOR)
  new_string.gsub!(/([A-Z\d]+)([A-Z][a-z])/, UNDERSCORE_DIVISION_TARGET)
  new_string.gsub!(/([a-z\d])([A-Z])/, UNDERSCORE_DIVISION_TARGET)
  new_string.gsub!(/[[:space:]]|\-/, UNDERSCORE_DIVISION_TARGET)
  new_string.downcase!
  self.class.new new_string
end