Sha256: a8567e87b75d7a604c6da299a6b5c96a4d59f1b531426dac4e47dc843226e583

Contents?: true

Size: 1.45 KB

Versions: 4

Compression:

Stored size: 1.45 KB

Contents

# frozen_string_literal: true

module Nocode
  module Util
    # Create a type -> class constant interface.  Classes can be registered as types.  Types
    # are snake-cased while class names are stored as pascal-cased.  Then constant! can be called
    # to retrieve the class constant by type.
    class ClassRegistry
      extend Forwardable

      class NotRegisteredError < StandardError; end

      attr_reader :types_to_classes

      def_delegators :types_to_classes, :to_s

      def initialize(types_to_classes = {})
        @types_to_classes = Dictionary.new(types_to_classes)

        freeze
      end

      def load(types, class_prefix: '', type_prefix: '')
        types.each do |type|
          pascal_cased = type.split(File::SEPARATOR).map do |part|
            part.split('_').collect(&:capitalize).join
          end.join('::')

          register("#{type_prefix}#{type}", "#{class_prefix}#{pascal_cased}")
        end

        self
      end

      def register(type, class_name)
        tap { types_to_classes[type] = class_name }
      end

      def unregister(type)
        tap { types_to_classes.delete(type) }
      end

      def constant!(type)
        name = types_to_classes[type]

        raise NotRegisteredError, "Constant not registered for: #{type}" if name.to_s.empty?

        if Object.const_defined?(name, false)
          Object.const_get(name, false)
        else
          Object.const_missing(name)
        end
      end
    end
  end
end

Version data entries

4 entries across 4 versions & 1 rubygems

Version Path
nocode-0.0.10 lib/nocode/util/class_registry.rb
nocode-0.0.9 lib/nocode/util/class_registry.rb
nocode-0.0.8 lib/nocode/util/class_registry.rb
nocode-0.0.7 lib/nocode/util/class_registry.rb