class NxtRegistry::Registry
Attributes
accessor[R]
config[R]
configured[RW]
interface_defined[RW]
is_leaf[RW]
mutex[R]
name[R]
namespace[R]
options[R]
parent[R]
patterns[R]
store[R]
Public Class Methods
new(name = object_id.to_s, **options, &config)
click to toggle source
# File lib/nxt_registry/registry.rb, line 3 def initialize(name = object_id.to_s, **options, &config) @options = options @name = name @parent = options[:parent] @is_leaf = true @namespace = build_namespace @config = config @store = {} @configured = false @patterns = [] @config = config @mutex = Mutex.new configure(&config) end
Public Instance Methods
[](key)
click to toggle source
# File lib/nxt_registry/registry.rb, line 111 def [](key) resolve!(key) end
[]=(key, value)
click to toggle source
# File lib/nxt_registry/registry.rb, line 115 def []=(key, value) register(key, value) end
allowed_keys(*keys)
click to toggle source
# File lib/nxt_registry/registry.rb, line 58 def allowed_keys(*keys) @allowed_keys ||= [] return @allowed_keys if keys.empty? @allowed_keys += keys.map { |key| transformed_key(key) } end
Also aliased as: attrs
attr(key)
click to toggle source
# File lib/nxt_registry/registry.rb, line 67 def attr(key) allowed_keys(key) # @deprecated end
configure(&block)
click to toggle source
# File lib/nxt_registry/registry.rb, line 142 def configure(&block) setup_defaults(options) define_accessors define_interface allowed_keys(*Array(options.fetch(:allowed_keys, []))) required_keys(*Array(options.fetch(:required_keys, []))) if block.present? if block.arity == 1 instance_exec(self, &block) else instance_exec(&block) end end validate_required_keys_given self.configured = true end
exclude?(key)
click to toggle source
# File lib/nxt_registry/registry.rb, line 131 def exclude?(key) store.exclude?(transformed_key(key)) end
fetch(key, *args, &block)
click to toggle source
# File lib/nxt_registry/registry.rb, line 135 def fetch(key, *args, &block) key = matching_key(key) store.fetch(key, *args, &block) end
include?(key)
click to toggle source
# File lib/nxt_registry/registry.rb, line 127 def include?(key) store.include?(transformed_key(key)) end
key?(key)
click to toggle source
# File lib/nxt_registry/registry.rb, line 123 def key?(key) store.key?(transformed_key(key)) end
keys()
click to toggle source
# File lib/nxt_registry/registry.rb, line 119 def keys store.keys.map(&method(:transformed_key)) end
level(name, **options, &config)
click to toggle source
# File lib/nxt_registry/registry.rb, line 22 def level(name, **options, &config) options = options.merge(parent: self) if is_a_blank?(default) self.is_leaf = false self.default = RegistryBuilder.new do Registry.new(name, **options, &config) end # Call the builder once to guarantee we do not create a registry with a broken setup default.call elsif default.is_a?(RegistryBuilder) raise ArgumentError, 'Multiple nestings on the same level' else raise ArgumentError, 'Default values cannot be defined on registries that nest others' end end
register(key = Blank.new, value = Blank.new, **options, &block)
click to toggle source
# File lib/nxt_registry/registry.rb, line 71 def register(key = Blank.new, value = Blank.new, **options, &block) if block_given? if is_a_blank?(value) registry(key, **options, &block) else raise_register_argument_error end else __register(key, value, raise_on_key_already_registered: true) end end
register!(key = Blank.new, value = Blank.new, **options, &block)
click to toggle source
# File lib/nxt_registry/registry.rb, line 83 def register!(key = Blank.new, value = Blank.new, **options, &block) if block_given? if is_a_blank?(value) registry!(key, **options, &block) else raise_register_argument_error end else __register(key, value, raise_on_key_already_registered: false) end end
registry(name, **options, &config)
click to toggle source
# File lib/nxt_registry/registry.rb, line 41 def registry(name, **options, &config) opts = conditionally_inherit_options(options) register(name, Registry.new(name, **opts, &config)) end
registry!(name, **options, &config)
click to toggle source
# File lib/nxt_registry/registry.rb, line 46 def registry!(name, **options, &config) opts = conditionally_inherit_options(options) register!(name, Registry.new(name, **opts, &config)) end
required_keys(*keys)
click to toggle source
# File lib/nxt_registry/registry.rb, line 51 def required_keys(*keys) @required_keys ||= [] return @required_keys if keys.empty? @required_keys += keys.map { |key| transformed_key(key) } end
resolve(*keys)
click to toggle source
# File lib/nxt_registry/registry.rb, line 101 def resolve(*keys) keys.inject(self) do |current_registry, key| current_registry.send(:__resolve, key, raise_on_key_not_registered: false) || break end end
resolve!(*keys)
click to toggle source
# File lib/nxt_registry/registry.rb, line 95 def resolve!(*keys) keys.inject(self) do |current_registry, key| current_registry.send(:__resolve, key, raise_on_key_not_registered: true) end end
to_h()
click to toggle source
# File lib/nxt_registry/registry.rb, line 107 def to_h store end
to_s()
click to toggle source
# File lib/nxt_registry/registry.rb, line 161 def to_s "Registry[#{name}] -> #{store.to_s}" end
Also aliased as: inspect
Private Instance Methods
__register(key, value, raise_on_key_already_registered: true)
click to toggle source
# File lib/nxt_registry/registry.rb, line 189 def __register(key, value, raise_on_key_already_registered: true) mutex.synchronize do key = if key.is_a?(Regexp) patterns << key key else transformed_key(key) end raise ArgumentError, "Not allowed to register values in a registry that contains nested registries" unless is_leaf raise KeyError, "Keys are restricted to #{allowed_keys}" if key_not_allowed?(key) on_key_already_registered && on_key_already_registered.call(key) if store[key] && raise_on_key_already_registered store[key] = value end end
__resolve(key, raise_on_key_not_registered: true)
click to toggle source
# File lib/nxt_registry/registry.rb, line 207 def __resolve(key, raise_on_key_not_registered: true) key = transformed_key(key) value = if is_leaf? resolved_key = key_resolver.call(key) if store.key?(resolved_key) store.fetch(resolved_key) elsif (pattern = matching_pattern(resolved_key)) store.fetch(pattern) else if is_a_blank?(default) return unless raise_on_key_not_registered on_key_not_registered && on_key_not_registered.call(key) else value = resolve_default(key) return value unless memoize store[key] ||= value end end else store[key] ||= default.call end value = call_or_value(value, key) resolver.call(value) end
build_namespace()
click to toggle source
# File lib/nxt_registry/registry.rb, line 360 def build_namespace parent ? name.to_s.prepend("#{parent.send(:namespace)}.") : name.to_s end
call_or_value(value, key)
click to toggle source
# File lib/nxt_registry/registry.rb, line 247 def call_or_value(value, key) return value unless call return value if value.is_a?(NxtRegistry::Registry) return value unless value.respond_to?(:call) args = [key, value] value.call(*args.take(value.arity)) end
conditionally_inherit_options(opts)
click to toggle source
# File lib/nxt_registry/registry.rb, line 172 def conditionally_inherit_options(opts) base = opts.delete(:inherit_options) ? options : {} base.merge(opts).merge(parent: self) end
define_accessors()
click to toggle source
# File lib/nxt_registry/registry.rb, line 307 def define_accessors %w[default memoize call resolver key_resolver transform_keys on_key_already_registered on_key_not_registered].each do |attribute| define_singleton_method attribute do |value = Blank.new, &block| value = block if block if is_a_blank?(value) instance_variable_get("@#{attribute}") else options[attribute.to_sym] ||= value instance_variable_set("@#{attribute}", value) end end define_singleton_method "#{attribute}=" do |value| options[attribute.to_sym] ||= value instance_variable_set("@#{attribute}", value) end end end
define_interface()
click to toggle source
# File lib/nxt_registry/registry.rb, line 260 def define_interface return if interface_defined raise_invalid_accessor_name(accessor) if respond_to?(accessor.to_s) accessor_with_bang = "#{accessor}!" raise_invalid_accessor_name(accessor_with_bang) if respond_to?(accessor_with_bang) define_singleton_method accessor.to_s do |key = Blank.new, value = Blank.new| return self if is_a_blank?(key) key = transformed_key(key) if is_a_blank?(value) resolve(key) else register(key, value) end end define_singleton_method accessor_with_bang do |key = Blank.new, value = Blank.new| return self if is_a_blank?(key) key = transformed_key(key) if is_a_blank?(value) resolve!(key) else register!(key, value) end end self.interface_defined = true end
initialize_copy(original)
click to toggle source
Calls superclass method
# File lib/nxt_registry/registry.rb, line 376 def initialize_copy(original) super @mutex = Mutex.new containers = %i[store options] variables = %i[patterns required_keys allowed_keys namespace on_key_already_registered on_key_not_registered] containers.each { |c| instance_variable_set("@#{c}", original.send(c).deep_dup) } variables.each { |v| instance_variable_set("@#{v}", original.send(v).dup) } end
is_a_blank?(value)
click to toggle source
# File lib/nxt_registry/registry.rb, line 368 def is_a_blank?(value) value.is_a?(Blank) end
is_leaf?()
click to toggle source
# File lib/nxt_registry/registry.rb, line 185 def is_leaf? @is_leaf end
key_not_allowed?(key)
click to toggle source
# File lib/nxt_registry/registry.rb, line 327 def key_not_allowed?(key) return if allowed_keys.empty? allowed_keys.exclude?(transformed_key(key)) end
matching_key(key)
click to toggle source
# File lib/nxt_registry/registry.rb, line 239 def matching_key(key) key = transformed_key(key) # if key is present it always wins over patterns return key if store.key?(key) matching_pattern(key) || key end
matching_pattern(key)
click to toggle source
# File lib/nxt_registry/registry.rb, line 256 def matching_pattern(key) patterns.find { |pattern| key.match?(pattern) } end
raise_invalid_accessor_name(name)
click to toggle source
# File lib/nxt_registry/registry.rb, line 372 def raise_invalid_accessor_name(name) raise ArgumentError, "#{self} already implements a method named: #{name}. Please choose a different accessor name" end
raise_key_already_registered_error(key)
click to toggle source
# File lib/nxt_registry/registry.rb, line 341 def raise_key_already_registered_error(key) raise NxtRegistry::Errors::KeyAlreadyRegisteredError, "Key '#{key}' already registered in registry '#{namespace}'" end
raise_key_not_registered_error(key)
click to toggle source
# File lib/nxt_registry/registry.rb, line 345 def raise_key_not_registered_error(key) raise NxtRegistry::Errors::KeyNotRegisteredError, "Key '#{key}' not registered in registry '#{namespace}'" end
raise_register_argument_error()
click to toggle source
# File lib/nxt_registry/registry.rb, line 364 def raise_register_argument_error raise ArgumentError, 'Either provide a key value pair or a block to register' end
resolve_default(key)
click to toggle source
# File lib/nxt_registry/registry.rb, line 333 def resolve_default(key) if call && default.respond_to?(:call) default.arity > 0 ? default.call(key) : default.call else default end end
setup_defaults(options)
click to toggle source
# File lib/nxt_registry/registry.rb, line 294 def setup_defaults(options) @default = options.fetch(:default) { Blank.new } @memoize = options.fetch(:memoize) { true } @call = options.fetch(:call) { true } @resolver = options.fetch(:resolver, ->(val) { val }) @key_resolver = options.fetch(:key_resolver, ->(val) { val }) @transform_keys = options.fetch(:transform_keys) { ->(key) { key.is_a?(Regexp) ? key : key.to_s } } @accessor = options.fetch(:accessor) { name } @on_key_already_registered = options.fetch(:on_key_already_registered) { ->(key) { raise_key_already_registered_error(key) } } @on_key_not_registered = options.fetch(:on_key_not_registered) { ->(key) { raise_key_not_registered_error(key) } } end
transformed_key(key)
click to toggle source
# File lib/nxt_registry/registry.rb, line 349 def transformed_key(key) @transformed_key ||= {} @transformed_key[key] ||= begin if transform_keys && !is_a_blank?(key) transform_keys.call(key) else key end end end
validate_required_keys_given()
click to toggle source
# File lib/nxt_registry/registry.rb, line 177 def validate_required_keys_given required_keys.each do |key| next if store.key?(key) raise Errors::RequiredKeyMissing, "Required key '#{key}' missing in #{self}" end end