2014-01-20 18:21:29 -05:00
|
|
|
module Pry::Config::Behavior
|
2014-03-30 19:47:53 -04:00
|
|
|
ASSIGNMENT = "=".freeze
|
|
|
|
NODUP = [TrueClass, FalseClass, NilClass, Symbol, Numeric, Module, Proc].freeze
|
|
|
|
INSPECT_REGEXP = /#{Regexp.escape "default=#<"}/
|
2014-01-20 18:21:29 -05:00
|
|
|
|
2014-03-17 07:27:57 -04:00
|
|
|
module Builder
|
|
|
|
def from_hash(hash, default = nil)
|
|
|
|
new(default).tap do |config|
|
|
|
|
config.merge!(hash)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-01-30 12:54:18 -05:00
|
|
|
def self.included(klass)
|
2014-03-17 07:22:07 -04:00
|
|
|
unless defined?(RESERVED_KEYS)
|
|
|
|
const_set :RESERVED_KEYS, instance_methods(false).map(&:to_s).freeze
|
|
|
|
end
|
2014-03-17 07:27:57 -04:00
|
|
|
klass.extend(Builder)
|
2014-01-30 12:54:18 -05:00
|
|
|
end
|
|
|
|
|
2014-01-27 01:16:10 -05:00
|
|
|
def initialize(default = Pry.config)
|
2014-04-30 03:51:59 -04:00
|
|
|
@default = default
|
2014-03-14 21:57:07 -04:00
|
|
|
@lookup = {}
|
2014-01-20 18:21:29 -05:00
|
|
|
end
|
|
|
|
|
2014-03-14 00:40:09 -04:00
|
|
|
#
|
|
|
|
# @return [Pry::Config::Behavior]
|
2014-03-23 03:26:40 -04:00
|
|
|
# returns the default used if a matching value for a key isn't found in self
|
2014-03-14 00:40:09 -04:00
|
|
|
#
|
|
|
|
def default
|
|
|
|
@default
|
|
|
|
end
|
|
|
|
|
2014-01-20 18:21:29 -05:00
|
|
|
def [](key)
|
2014-03-14 21:57:07 -04:00
|
|
|
@lookup[key.to_s]
|
2014-01-20 18:21:29 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def []=(key, value)
|
2014-01-27 04:06:06 -05:00
|
|
|
key = key.to_s
|
|
|
|
if RESERVED_KEYS.include?(key)
|
2014-03-14 04:13:55 -04:00
|
|
|
raise ArgumentError, "few things are reserved by pry, but using '#{key}' as a configuration key is."
|
2014-01-27 04:06:06 -05:00
|
|
|
end
|
2014-03-14 21:57:07 -04:00
|
|
|
@lookup[key] = value
|
2014-01-20 18:21:29 -05:00
|
|
|
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]
|
2014-01-27 23:39:05 -05:00
|
|
|
elsif key?(key)
|
2014-01-20 18:21:29 -05:00
|
|
|
self[key]
|
|
|
|
elsif @default.respond_to?(name)
|
2014-01-25 17:55:15 -05:00
|
|
|
value = @default.public_send(name, *args, &block)
|
2014-04-30 03:51:59 -04:00
|
|
|
# FIXME: refactor Pry::Hook so that it stores config on the config object,
|
|
|
|
# so that we can use the normal strategy.
|
|
|
|
self[key] = value.dup if key == 'hooks'
|
|
|
|
value
|
2014-01-20 18:21:29 -05:00
|
|
|
else
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def merge!(other)
|
2014-03-23 04:57:59 -04:00
|
|
|
other = try_convert_to_hash(other)
|
2014-03-23 03:26:40 -04:00
|
|
|
raise TypeError, "unable to convert argument into a Hash" unless other
|
2014-01-29 19:37:58 -05:00
|
|
|
other.each do |key, value|
|
|
|
|
self[key] = value
|
|
|
|
end
|
2014-01-20 18:21:29 -05:00
|
|
|
end
|
|
|
|
|
2014-03-23 04:57:59 -04:00
|
|
|
def ==(other)
|
2014-03-23 05:02:22 -04:00
|
|
|
@lookup == try_convert_to_hash(other)
|
2014-03-23 04:57:59 -04:00
|
|
|
end
|
|
|
|
alias_method :eql?, :==
|
|
|
|
|
2014-03-23 05:16:13 -04:00
|
|
|
def respond_to_missing?(key, include_private=false)
|
2014-03-23 03:26:40 -04:00
|
|
|
key?(key) or @default.respond_to?(key) or super(key, include_private)
|
2014-01-27 01:02:55 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def key?(key)
|
|
|
|
key = key.to_s
|
2014-03-14 21:57:07 -04:00
|
|
|
@lookup.key?(key)
|
2014-01-20 18:21:29 -05:00
|
|
|
end
|
|
|
|
|
2014-03-14 22:05:19 -04:00
|
|
|
def clear
|
2014-03-14 21:57:07 -04:00
|
|
|
@lookup.clear
|
2014-01-27 00:11:15 -05:00
|
|
|
true
|
|
|
|
end
|
2014-03-14 22:05:19 -04:00
|
|
|
alias_method :refresh, :clear
|
2014-01-27 00:11:15 -05:00
|
|
|
|
2014-01-28 11:20:58 -05:00
|
|
|
def forget(key)
|
2014-03-14 21:57:07 -04:00
|
|
|
@lookup.delete(key.to_s)
|
2014-01-27 00:00:29 -05:00
|
|
|
end
|
|
|
|
|
2014-02-02 17:23:23 -05:00
|
|
|
def keys
|
2014-03-14 21:57:07 -04:00
|
|
|
@lookup.keys
|
2014-02-02 17:23:23 -05:00
|
|
|
end
|
|
|
|
|
2014-01-20 18:21:29 -05:00
|
|
|
def to_hash
|
2014-03-14 21:57:07 -04:00
|
|
|
@lookup.dup
|
2014-01-20 18:21:29 -05:00
|
|
|
end
|
2014-01-28 09:37:07 -05:00
|
|
|
alias_method :to_h, :to_hash
|
2014-01-20 18:21:29 -05:00
|
|
|
|
2014-03-30 13:59:57 -04:00
|
|
|
|
|
|
|
def inspect
|
|
|
|
key_str = keys.map { |key| "'#{key}'" }.join(",")
|
2014-03-30 19:47:53 -04:00
|
|
|
"#<#{_clip_inspect(self)} local_keys=[#{key_str}] default=#{@default.inspect}>"
|
|
|
|
end
|
|
|
|
|
|
|
|
def pretty_print(q)
|
|
|
|
q.text inspect[1..-1].gsub(INSPECT_REGEXP, "default=<")
|
2014-03-30 13:59:57 -04:00
|
|
|
end
|
|
|
|
|
2014-01-25 17:55:15 -05:00
|
|
|
private
|
2014-03-30 13:59:57 -04:00
|
|
|
def _clip_inspect(obj)
|
|
|
|
"#{obj.class}:0x%x" % obj.object_id << 1
|
|
|
|
end
|
|
|
|
|
2014-01-25 17:55:15 -05:00
|
|
|
def _dup(value)
|
|
|
|
if NODUP.any? { |klass| klass === value }
|
|
|
|
value
|
|
|
|
else
|
|
|
|
value.dup
|
|
|
|
end
|
|
|
|
end
|
2014-03-23 04:57:59 -04:00
|
|
|
|
|
|
|
def try_convert_to_hash(obj)
|
|
|
|
if Hash === obj
|
|
|
|
obj
|
|
|
|
elsif obj.respond_to?(:to_h)
|
|
|
|
obj.to_h
|
|
|
|
elsif obj.respond_to?(:to_hash)
|
|
|
|
obj.to_hash
|
|
|
|
else
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
end
|
2014-01-20 18:21:29 -05:00
|
|
|
end
|