mirror of
https://github.com/pry/pry.git
synced 2022-11-09 12:35:05 -05:00
123 lines
2.5 KiB
Ruby
123 lines
2.5 KiB
Ruby
module Pry::Config::Behavior
|
|
ASSIGNMENT = "=".freeze
|
|
NODUP = [TrueClass, FalseClass, NilClass, Symbol, Numeric, Module, Proc].freeze
|
|
RESERVED_KEYS = [
|
|
"[]", "[]=", "merge!",
|
|
"respond_to?", "key?", "refresh",
|
|
"forget", "default_for", "to_h",
|
|
"to_hash", "_dup", "default"
|
|
].freeze
|
|
|
|
def self.included(klass)
|
|
klass.extend Module.new {
|
|
def from_hash(hash, default = nil)
|
|
new(default).tap do |config|
|
|
config.merge!(hash)
|
|
end
|
|
end
|
|
}
|
|
end
|
|
|
|
def initialize(default = Pry.config)
|
|
if default
|
|
@default = default.dup
|
|
@default.default_for(self)
|
|
end
|
|
@default_for = nil
|
|
@lookup = {}
|
|
end
|
|
|
|
#
|
|
# @return [Pry::Config::Behavior]
|
|
# returns the fallback used when a key is not found locally.
|
|
#
|
|
def default
|
|
@default
|
|
end
|
|
|
|
def [](key)
|
|
@lookup[key.to_s]
|
|
end
|
|
|
|
def []=(key, value)
|
|
key = key.to_s
|
|
if RESERVED_KEYS.include?(key)
|
|
raise ArgumentError, "few things are reserved by pry, but using '#{key}' as a configuration key is."
|
|
end
|
|
@lookup[key] = value
|
|
end
|
|
|
|
def method_missing(name, *args, &block)
|
|
key = name.to_s
|
|
if key[-1] == ASSIGNMENT
|
|
short_key = key[0..-2]
|
|
self[short_key] = args[0]
|
|
elsif key?(key)
|
|
self[key]
|
|
elsif @default.respond_to?(name)
|
|
value = @default.public_send(name, *args, &block)
|
|
self[key] = _dup(value)
|
|
else
|
|
nil
|
|
end
|
|
end
|
|
|
|
def merge!(other)
|
|
raise TypeError, "cannot coerce argument to Hash" unless other.respond_to?(:to_hash)
|
|
other = other.to_hash
|
|
other.each do |key, value|
|
|
self[key] = value
|
|
end
|
|
end
|
|
|
|
def respond_to?(name, boolean=false)
|
|
key?(name) or @default.respond_to?(name) or super(name, boolean)
|
|
end
|
|
|
|
def key?(key)
|
|
key = key.to_s
|
|
@lookup.key?(key)
|
|
end
|
|
|
|
def clear
|
|
@lookup.clear
|
|
true
|
|
end
|
|
alias_method :refresh, :clear
|
|
|
|
def forget(key)
|
|
@lookup.delete(key.to_s)
|
|
end
|
|
|
|
def default_for(other)
|
|
if @default_for
|
|
raise RuntimeError, "self is already the default for %s" % [Pry.view_clip(@default_for, id: true)]
|
|
else
|
|
@default_for = other
|
|
end
|
|
end
|
|
|
|
def ==(other)
|
|
return false unless other.respond_to?(:to_hash)
|
|
to_hash == other.to_hash
|
|
end
|
|
alias_method :eql?, :==
|
|
|
|
def keys
|
|
@lookup.keys
|
|
end
|
|
|
|
def to_hash
|
|
@lookup.dup
|
|
end
|
|
alias_method :to_h, :to_hash
|
|
|
|
private
|
|
def _dup(value)
|
|
if NODUP.any? { |klass| klass === value }
|
|
value
|
|
else
|
|
value.dup
|
|
end
|
|
end
|
|
end
|