# frozen_string_literal: true module Hanami class View # Builds scope objects via matching classes # # @api private class ScopeBuilder class << self # Returns a new scope using a class matching the name # # @param name [Symbol, Class] scope name # @param locals [Hash] locals hash # # @return [Hanami::View::Scope] # # @api private def call(name = nil, locals:, rendering:) # rubocop:disable Style/OptionalArguments klass = scope_class(name, rendering: rendering) klass.new(name: name, locals: locals, rendering: rendering) end private def scope_class(name = nil, rendering:) if name.nil? rendering.config.scope_class elsif name.is_a?(Class) name else View.cache.fetch_or_store(:scope_class, rendering.config) do resolve_scope_class(name: name, rendering: rendering) end end end def resolve_scope_class(name:, rendering:) name = rendering.inflector.camelize(name.to_s) namespace = rendering.config.scope_namespace # Give autoloaders a chance to act begin klass = namespace.const_get(name) rescue NameError # rubocop:disable Lint/HandleExceptions end if !klass && namespace.const_defined?(name, false) klass = namespace.const_get(name) end if klass && klass < Scope klass else rendering.config.scope_class end end end end end end