class NameOfPerson::PersonName

def self.full(full_name)

def self.full(full_name)
  first, last = full_name.to_s.squish.split(/\s/, 2)
  new(first, last) if first.present?
end

def abbreviated

Returns first initial + last, such as "J. Fried".
def abbreviated
  @abbreviated ||= last.present? ? "#{first.first}. #{last}" : first
end

def encode_with(coder)

Override to_yaml to serialize as a plain string.
def encode_with(coder)
  coder.represent_scalar nil, to_s
end

def familiar

Returns first + last initial, such as "Jason F.".
def familiar
  @familiar ||= last.present? ? "#{first} #{last.first}." : first
end

def full

Returns first + last, such as "Jason Fried".
def full
  @full ||= last.present? ? "#{first} #{last}" : first
end

def initialize(first, last = nil)

def initialize(first, last = nil)
  raise ArgumentError, "First name is required" unless first.present?
  @first, @last = first, last
  super full
end

def initials

Returns just the initials.
def initials
  @initials ||= remove(/(\(|\[).*(\)|\])/).scan(/([[:word:]])[[:word:]]*/i).join
end

def mentionable

Returns a mentionable version of the familiar name
def mentionable
  @mentionable ||= familiar.chop.delete(' ').downcase
end

def possessive(method = :full)

Returns full name with with trailing 's or ' if name ends in s.
def possessive(method = :full)
  whitelist = %i[full first last abbreviated sorted initials]
  unless whitelist.include?(method.to_sym)
    raise ArgumentError, 'Please provide a valid method'
  end
  name = public_send(method)
  @possessive ||= "#{name}'#{'s' unless name.downcase.end_with?('s')}"
end

def sorted

Returns last + first for sorting.
def sorted
  @sorted ||= last.present? ? "#{last}, #{first}" : first
end