class OptionalArgument::Store

@note

"To be Enumerable" is not necessary for this class.
Because main role is just to hold options.

Public Class Methods

adjuster?(name) click to toggle source

@param name [Symbol, String, to_sym]

# File lib/optionalargument/store/singleton_class.rb, line 108
def adjuster?(name)
  member?(name) && @adjusters.key?(autonym_for_name(name))
end
aliased?(name) click to toggle source

@param name [Symbol, String, to_sym]

# File lib/optionalargument/store/singleton_class.rb, line 88
def aliased?(name)
  member?(name) && !autonym?(name) && !deprecated?(name)
end
aliases() click to toggle source

@return [Array<Symbol>]

# File lib/optionalargument/store/singleton_class.rb, line 68
def aliases
  @names.each_key.select { |name| aliased?(name) }
end
autonym?(name) click to toggle source

@param name [Symbol, String, to_sym]

# File lib/optionalargument/store/singleton_class.rb, line 78
def autonym?(name)
  @names.value?(name.to_sym)
end
autonym_for(name)
Alias for: autonym_for_name
autonym_for_name(name) click to toggle source

@param name [Symbol, String, to_sym] @return [Symbol]

# File lib/optionalargument/store/singleton_class.rb, line 51
def autonym_for_name(name)
  @names.fetch(name.to_sym)
end
Also aliased as: autonym_for
autonyms() click to toggle source

@return [Array<Symbol>] - autonym, autonym, …

# File lib/optionalargument/store/singleton_class.rb, line 58
def autonyms
  @names.values.uniq
end
condition?(name) click to toggle source

@param name [Symbol, String, to_sym]

# File lib/optionalargument/store/singleton_class.rb, line 103
def condition?(name)
  member?(name) && @conditions.key?(autonym_for_name(name))
end
default?(name) click to toggle source

@param name [Symbol, String, to_sym]

# File lib/optionalargument/store/singleton_class.rb, line 98
def default?(name)
  member?(name) && @default_values.key?(autonym_for_name(name))
end
deprecated?(name) click to toggle source

@param name [Symbol, String, to_sym]

# File lib/optionalargument/store/singleton_class.rb, line 93
def deprecated?(name)
  @deprecateds.include?(name.to_sym)
end
deprecateds() click to toggle source

@return [Array<Symbol>]

# File lib/optionalargument/store/singleton_class.rb, line 73
def deprecateds
  @deprecateds.dup
end
for_options(options, defined_only: true, exception: nil)
Alias for: parse
for_pairs(options, defined_only: true, exception: nil)
Alias for: parse
member?(name) click to toggle source

@param name [Symbol, String, to_sym]

# File lib/optionalargument/store/singleton_class.rb, line 83
def member?(name)
  @names.key?(name.to_sym)
end
members() click to toggle source

@return [Array<Symbol>]

# File lib/optionalargument/store/singleton_class.rb, line 63
def members
  @names.keys
end
names_with_autonym() click to toggle source

for debug @return [Hash] - autonym/alias/deprecated => autonym, …

# File lib/optionalargument/store/singleton_class.rb, line 114
def names_with_autonym
  @names.dup
end
parse(options, defined_only: true, exception: nil) click to toggle source

@param [Boolean] defined_only @param [Exception] exception @return [Store] instance of a Store’s subclass

# File lib/optionalargument/store/singleton_class.rb, line 23
def parse(options, defined_only: true, exception: nil)
  begin
    unless options.respond_to?(:each_pair)
      raise MalformedOptionsError, 'options must be key-value pairs'
    end

    autonym_hash = _autonym_hash_for(options, defined_only)
    _scan_hash!(autonym_hash)

    new(autonym_hash)
  rescue MalformedOptionsError, InvalidWritingError => err
    if replacement = exception
      raise replacement.new, err
    else
      raise err
    end
  end
end
Also aliased as: for_options, for_pairs

Private Class Methods

_add_adjuster(autonym, adjuster) click to toggle source

@param autonym [Symbol] @param adjuster [#call] @return [adjuster]

# File lib/optionalargument/store/singleton_class.rb, line 339
def _add_adjuster(autonym, adjuster)
  unless adjuster.respond_to?(:call)
    raise TypeError, "#{adjuster.inspect} is wrong object for adjuster"
  end

  @adjusters[autonym] = adjuster
end
_add_condition(autonym, condition) click to toggle source

@param autonym [Symbol] @param condition [#===] @return [condition]

# File lib/optionalargument/store/singleton_class.rb, line 328
def _add_condition(autonym, condition)
  unless condition.respond_to?(:===)
    raise TypeError, "#{condition.inspect} is wrong object for condition"
  end

  @conditions[autonym] = condition
end
_add_default(autonym, value) click to toggle source

@param autonym [Symbol] @return [value]

# File lib/optionalargument/store/singleton_class.rb, line 321
def _add_default(autonym, value)
  @default_values[autonym] = value
end
_add_deprecated(*names) click to toggle source

@param names [Array<Symbol>] @return [nil]

# File lib/optionalargument/store/singleton_class.rb, line 290
def _add_deprecated(*names)
  @deprecateds.concat(names)
  nil
end
_add_member(autonym, name) click to toggle source

@param autonym [Symbol] @param name [Symbol] @return [name]

# File lib/optionalargument/store/singleton_class.rb, line 298
def _add_member(autonym, name)
  if member?(name)
    raise NameError, "already defined the name: #{name}"
  end

  @names[name] = autonym
  _def_instance_methods(name)
end
_add_must(autonym) click to toggle source

@param autonym [Symbol] @return [autonym]

# File lib/optionalargument/store/singleton_class.rb, line 284
def _add_must(autonym)
  @must_autonyms << autonym
end
_add_requirements(autonym, requirements) click to toggle source

@param autonym [Symbol] @param requirements [Array<Symbol, String, to_sym>] @return [nil]

# File lib/optionalargument/store/singleton_class.rb, line 310
def _add_requirements(autonym, requirements)
  unless requirements.kind_of?(Array) && requirements.all? { |name| name.respond_to?(:to_sym) }
    raise ArgumentError, '`requirements` requires to be Array<Symbol, String>'
  end

  @requirements[autonym] = requirements.map(&:to_sym).uniq
  nil
end
_autonym_hash_for(options, defined_only) click to toggle source

@param options [#each_pair] @param defined_only [Boolean] @return [Hash]

# File lib/optionalargument/store/singleton_class.rb, line 359
def _autonym_hash_for(options, defined_only)
  hash = {}

  options.each_pair do |key, value|
    key = key.to_sym

    if member?(key)
      autonym = autonym_for_name(key)
      raise KeyConflictError, key if hash.key?(autonym)

      if deprecated?(key)
        warn("`#{key}` is deprecated, use `#{autonym}`")
      end

      hash[autonym] = _validate_value(autonym, value)
    else
      if defined_only
        raise MalformedOptionsError, %Q!unknown defined name "#{key}"!
      end
    end
  end

  hash
end
_check_requirements() click to toggle source

@return [nil]

# File lib/optionalargument/store/singleton_class.rb, line 452
def _check_requirements
  @requirements.each_pair do |autonym, names|
    names.map! { |name|
      if member?(name)
        autonym_for_name(name)
      else
        raise ArgumentError,
              "`#{autonym}` with invalid requirements `#{names}`"
      end
    }
  end

  nil
end
_def_instance_methods(name) click to toggle source

@param name [Symbol] @return [nil]

# File lib/optionalargument/store/singleton_class.rb, line 229
def _def_instance_methods(name)
  autonym = autonym_for_name(name)
  fetcher = :"fetch_by_#{name}"

  define_method(fetcher) do
    self[autonym]
  end

  alias_method(name, fetcher)

  with_predicator = :"with_#{name}?"

  define_method(with_predicator) do
    with?(autonym)
  end

  predicator = :"#{name}?"
  alias_method(predicator, with_predicator)

  overrides = [name, fetcher, with_predicator, predicator].select { |callee|
    Store.method_defined?(callee) || Store.private_method_defined?(callee)
  }

  unless overrides.empty?
    warn("override methods: #{overrides.join(', ')}")
  end

  nil
end
_default_pairs_for(*autonyms) click to toggle source

@param autonyms [Array<Symbol>] @return [Hash] autonym => default_value

# File lib/optionalargument/store/singleton_class.rb, line 441
def _default_pairs_for(*autonyms)
  {}.tap { |h|
    autonyms.each do |autonym|
      if default?(autonym)
        h[autonym] = _validate_value(autonym, @default_values.fetch(autonym))
      end
    end
  }
end
_fix() click to toggle source

@return [nil]

# File lib/optionalargument/store/singleton_class.rb, line 139
def _fix
  raise 'no assigned members yet' if @names.empty?

  instance_variables.each do |var|
    instance_variable_get(var).freeze
  end

  _check_requirements

  nil
end
_init() click to toggle source

@return [nil]

# File lib/optionalargument/store/singleton_class.rb, line 125
def _init
  @names = {}                 # {autonym/alias/deprecated => autonym, ...}
  @must_autonyms = []         # [autonym, autonym, ...]
  @conflict_autonym_sets = [] # [[*autonyms], [*autonyms], ...]
  @requirements = {}          # {autonym => [*requirements], ...]
  @deprecateds = []           # [deprecated, deprecated, ...]
  @default_values = {}        # {autonym => value, ...}
  @conditions = {}            # {autonym => condition, ...}
  @adjusters = {}             # {autonym => adjuster, ...}

  nil
end
_scan_hash!(autonym_hash) click to toggle source

@param autonym_hash [Hash] @return [autonym_hash]

# File lib/optionalargument/store/singleton_class.rb, line 349
def _scan_hash!(autonym_hash)
  received_autonyms = autonym_hash.keys.map { |key| autonym_for_name(key) }
  _validate_autonym_combinations(*received_autonyms)
  autonym_hash.update(_default_pairs_for(*(autonyms - received_autonyms)))
  autonym_hash
end
_validate_autonym_combinations(*received_autonyms) click to toggle source

@param received_autonyms [Array<Symbol>] @raise [MalformedOptionsError, KeyConflictError] if invalid autonym combinations @return [nil]

# File lib/optionalargument/store/singleton_class.rb, line 387
def _validate_autonym_combinations(*received_autonyms)
  _validate_shortage_keys(*received_autonyms)
  _validate_requirements(*received_autonyms)
  _validate_conflicts(*received_autonyms)
  nil
end
_validate_conflicts(*received_autonyms) click to toggle source

@param received_autonyms [Array<Symbol>] @raise [KeyConflictError] @return [nil]

# File lib/optionalargument/store/singleton_class.rb, line 426
def _validate_conflicts(*received_autonyms)
  conflicts = @conflict_autonym_sets.find { |conflict_autonym_set|
    (conflict_autonym_set - received_autonyms).empty?
  }

  if conflicts
    raise KeyConflictError,
          "conflict combination thrown: #{conflicts.join(', ')}"
  end

  nil
end
_validate_requirements(*received_autonyms) click to toggle source

@param received_autonyms [Array<Symbol>] @raise [MalformedOptionsError] @return [nil]

# File lib/optionalargument/store/singleton_class.rb, line 411
def _validate_requirements(*received_autonyms)
  received_autonyms.each do |autonym|
    shortage_keys = @requirements.fetch(autonym) - received_autonyms
    unless shortage_keys.empty?
      raise MalformedOptionsError,
            "shortage option parameter for #{autonym}: #{shortage_keys.join(', ')}"
    end
  end

  nil
end
_validate_shortage_keys(*received_autonyms) click to toggle source

@param received_autonyms [Array<Symbol>] @raise [MalformedOptionsError] @return [nil]

# File lib/optionalargument/store/singleton_class.rb, line 397
def _validate_shortage_keys(*received_autonyms)
  shortage_keys = @must_autonyms - received_autonyms

  unless shortage_keys.empty?
    raise MalformedOptionsError,
          "shortage option parameter: #{shortage_keys.join(', ')}"
  end

  nil
end
_validate_value(autonym, value) click to toggle source

@param autonym [Symbol] @return [value]

# File lib/optionalargument/store/singleton_class.rb, line 261
def _validate_value(autonym, value)
  if adjuster?(autonym)
    adjuster = @adjusters.fetch(autonym)
    begin
      value = adjuster.call(value)
    rescue Exception => err
      raise InvalidAdjustingError, err
    end
  end

  if condition?(autonym)
    condition = @conditions.fetch(autonym)

    unless condition === value
      raise InvalidWritingError, "#{value.inspect} is deficient for #{condition}"
    end
  end

  value
end
add_conflict(autonym1, autonym2, *autonyms) click to toggle source

@param autonym1 [Symbol, String, to_sym] @param autonym2 [Symbol, String, to_sym] @param autonyms [Symbol, String, to_sym] @return [nil]

# File lib/optionalargument/store/singleton_class.rb, line 204
def add_conflict(autonym1, autonym2, *autonyms)
  autonyms = [autonym1, autonym2, *autonyms].map(&:to_sym)
  raise ArgumentError unless autonyms == autonyms.uniq

  not_autonyms = (autonyms - @names.values)
  unless not_autonyms.empty?
    raise ArgumentError, "contain not autonym: #{not_autonyms.join(', ')}"
  end
  raise if @conflict_autonym_sets.include?(autonyms)

  @conflict_autonym_sets << autonyms
  nil
end
Also aliased as: conflict
add_option(autonym, condition: nil, adjuster: nil, must: false, default: nil, requirements: [].freeze, deprecateds: [].freeze, aliases: [].freeze) click to toggle source

@param [Symbol, String, to_sym] autonym @param [Boolean] must @param [#===] condition @param [Array<Symbol, String, to_sym>] aliases @param [Array<Symbol, String, to_sym>] deprecateds @param [Array<Symbol, String, to_sym>] requirements @param [#call] adjuster @return [void]

# File lib/optionalargument/store/singleton_class.rb, line 163
def add_option(autonym, condition: nil, adjuster: nil, must: false, default: nil, requirements: [].freeze, deprecateds: [].freeze, aliases: [].freeze)
  autonym = autonym.to_sym

  if condition
    _add_condition(autonym, condition)
  end

  if adjuster
    _add_adjuster(autonym, adjuster)
  end

  if must
    unless default.nil?
      raise KeyConflictError, '"must" conflict with "default"'
    end

    _add_must(autonym)
  end

  unless default.nil?
    _add_default(autonym, default)
  end

  _add_requirements(autonym, requirements)

  _add_deprecated(*deprecateds)

  [autonym, *aliases, *deprecateds].each do |name|
    _add_member(autonym, name.to_sym)
  end

  nil
end
Also aliased as: opt, on
conflict(autonym1, autonym2, *autonyms)
Alias for: add_conflict
new(pairs) click to toggle source

@param pairs [Hash, to_hash]

# File lib/optionalargument/store.rb, line 21
def initialize(pairs)
  @pairs = pairs
end
on(autonym, condition: nil, adjuster: nil, must: false, default: nil, requirements: [].freeze, deprecateds: [].freeze, aliases: [].freeze)
Alias for: add_option
opt(autonym, condition: nil, adjuster: nil, must: false, default: nil, requirements: [].freeze, deprecateds: [].freeze, aliases: [].freeze)
Alias for: add_option

Public Instance Methods

==(other) click to toggle source

@return [Boolean]

# File lib/optionalargument/store.rb, line 77
def ==(other)
  other.instance_of?(__class__) && (other._pairs === @pairs)
end
Also aliased as: ===
===(other)
Alias for: ==
[](name) click to toggle source

@param name [Symbol, String, to_sym]

# File lib/optionalargument/store.rb, line 35
def [](name)
  @pairs[_autonym_for_name(name)]
end
autonym_for_name(name) click to toggle source

@param name [Symbol, String, to_sym] @return [Symbol]

# File lib/optionalargument/store.rb, line 27
def autonym_for_name(name)
  __class__.autonym_for_name(name)
end
Also aliased as: _autonym_for_name
each_pair(&block) click to toggle source

@yield [autonym, value] @yieldparam autonym [Symbol] @yieldreturn [self] @return [Enumerator]

# File lib/optionalargument/store.rb, line 55
def each_pair(&block)
  return _to_enum(__method__) { @pairs.size } unless block

  @pairs.each_pair(&block)
  self
end
eql?(other) click to toggle source
# File lib/optionalargument/store.rb, line 72
def eql?(other)
  other.instance_of?(__class__) && other._pairs.eql?(@pairs)
end
hash() click to toggle source

@return [Integer]

# File lib/optionalargument/store.rb, line 68
def hash
  @pairs.hash
end
inspect() click to toggle source

@return [String]

# File lib/optionalargument/store.rb, line 45
def inspect
  "#<optargs: #{@pairs.map { |k, v| "#{k}=#{v.inspect}" }.join(', ')}>"
end
Also aliased as: to_s
to_h() click to toggle source

@return [Hash]

# File lib/optionalargument/store.rb, line 63
def to_h
  @pairs.to_hash.dup
end
to_s()
Alias for: inspect
with?(name) click to toggle source

@param name [Symbol, String, to_sym]

# File lib/optionalargument/store.rb, line 40
def with?(name)
  @pairs.key?(_autonym_for_name(name))
end

Protected Instance Methods

_pairs() click to toggle source
# File lib/optionalargument/store.rb, line 85
def _pairs
  @pairs
end

Private Instance Methods

_autonym_for_name(name)
Alias for: autonym_for_name