class MoreMath::StringNumeral

def self.from(object, alphabet = 'a'..'z')

def self.from(object, alphabet = 'a'..'z')
  if object.respond_to?(:to_str)
    StringNumeral.from_string(object.to_str, alphabet)
  elsif object.respond_to?(:to_int)
    StringNumeral.from_number(object.to_int, alphabet)
  else
    StringNumeral.from_string(object.to_s, alphabet)
  end
end

def self.from_number(number, alphabet)

def self.from_number(number, alphabet)
  new nil, number, alphabet
end

def self.from_string(string, alphabet)

def self.from_string(string, alphabet)
  new string, nil, alphabet
end

def %(other)

def %(other)
  self.class.from_number((number % naturalize(other)), @alphabet)
end

def &(other)

def &(other)
  self.class.from_number(number & naturalize(other), @alphabet)
end

def *(other)

def *(other)
  self.class.from_number(number * naturalize(other), @alphabet)
end

def **(other)

def **(other)
  self.class.from_number(number ** naturalize(other), @alphabet)
end

def +(other)

def +(other)
  self.class.from_number(number + naturalize(other), @alphabet)
end

def -(other)

def -(other)
  self.class.from_number(naturalize(number - other), @alphabet)
end

def /(other)

def /(other)
  self.class.from_number((number / naturalize(other)), @alphabet)
end

def <<(other)

def <<(other)
  self.class.from_number(number << naturalize(other), @alphabet)
end

def >>(other)

def >>(other)
  self.class.from_number(number >> naturalize(other), @alphabet)
end

def [](other)

def [](other)
  self.class.from_number(number[other.to_i], @alphabet)
end

def ^(other)

def ^(other)
  self.class.from_number(number ^ naturalize(other), @alphabet)
end

def coerce(other)

def coerce(other)
  [ naturalize(other), number ]
end

def initialize(string, number, alphabet)

def initialize(string, number, alphabet)
  @alphabet = NumberifyStringFunction.convert_alphabet(alphabet).freeze
  if string
    @string = string.to_s
    string.each_char.each do |c|
      @alphabet.include?(c) or raise ArgumentError,
        "illegal character #{c.inspect} in #{@string.inspect} for alphabet #{@alphabet.inspect}"
    end
  elsif number
    @number = number.to_i
  end
end

def inspect

def inspect
  "#<#{self.class}: #{string.inspect} #{number.inspect}>"
end

def naturalize(number)

def naturalize(number)
  number = number.to_i
  number < 0 ? 0 : number
end

def number

def number
  @number ||= numberify_string(@string, @alphabet)
end

def pred

def pred
  self.class.from_number(naturalize(number - 1), @alphabet)
end

def pred!

def pred!
  @number = naturalize(@number - 1)
  @string = nil
  self
end

def string

def string
  @string ||= stringify_number(@number, @alphabet).freeze
end

def succ

def succ
  self.class.from_number(number + 1, @alphabet)
end

def succ!

def succ!
  @number += 1
  @string = nil
  self
end

def to_string_numeral

def to_string_numeral
  self
end

def |(other)

def |(other)
  self.class.from_number(number | naturalize(other), @alphabet)
end