Module: Hanami::Slice::ClassMethods
- Defined in:
- lib/hanami/slice.rb
Overview
Instance Attribute Summary collapse
-
#autoloader ⇒ Zeitwerk::Loader
readonly
Returns the slice’s autoloader.
-
#container ⇒ Object
readonly
Returns the slice’s container.
-
#parent ⇒ Hanami::Slice
readonly
Returns the slice’s parent.
Instance Method Summary collapse
-
#[](key) ⇒ Object
Resolves the component with the given key from the container.
-
#app ⇒ Hanami::App
Returns the Hanami app.
-
#app? ⇒ Boolean
Returns true if the slice is Hanami.app.
-
#boot ⇒ self
Boots the slice.
-
#booted? ⇒ Boolean
Returns true if the slice has been booted.
-
#call(rack_env) ⇒ Array
Calls the slice’s [Rack] app and returns a Rack-compatible response object.
-
#config ⇒ Hanami::Config
Returns the slice’s config.
- #configure_provider(*args, **kwargs, &block) ⇒ Object
-
#environment(env_name, &block) ⇒ self
Evaluates the block for a given app environment only.
-
#export(keys) ⇒ self
Specifies the components to export from the slice.
-
#import(from:, as: nil, keys: nil) ⇒ Object
Specifies components to import from another slice.
-
#inflector ⇒ Dry::Inflector
Returns the slice’s configured inflector.
-
#key?(key) ⇒ Boolean
Returns true if the component with the given key is registered in the container.
-
#keys ⇒ Array<String>
Returns an array of keys for all currently registered components in the container.
-
#namespace ⇒ Module
Returns the constant for the slice’s module namespace.
- #prepare(provider_name = nil) ⇒ Object
-
#prepare_container {|container| ... } ⇒ self
Captures the given block to be called with the slice’s container during the slice’s ‘prepare` step, after the slice has already configured the container.
-
#prepared? ⇒ Boolean
Returns true if the slice has been prepared.
-
#rack_app ⇒ #call?
Returns a [Rack] app for the slice, or nil if no routes are defined.
-
#register ⇒ container
Registers a component in the slice’s container.
-
#register_provider(name, namespace: nil, from: nil, source: nil) ⇒ container
Registers a provider and its lifecycle hooks.
- #register_slice ⇒ slices
-
#registered? ⇒ Boolean
Required for the slice to act as a provider target.
-
#relative_source_path ⇒ Pathname
Returns the slice’s root component directory, as a path relative to the app’s root.
- #resolve ⇒ Object
-
#root ⇒ Pathname
Returns the slice’s root, either the root as explicitly configured, or a default fallback of the slice’s name within the app’s ‘slices/` dir.
-
#router(inspector: nil) ⇒ Hanami::Slice::Router?
Returns the slice’s router, if or nil if no routes are defined.
-
#routes ⇒ Hanami::Routes?
Returns the slice’s routes, or nil if no routes are defined.
-
#settings ⇒ Hanami::Settings?
Returns the slice’s settings, or nil if no settings are defined.
-
#shutdown ⇒ self
Shuts down the slice’s providers, as well as the providers in any nested slices.
-
#slice_name ⇒ SliceName
Returns a Hanami::SliceName for the slice, an object with methods returning the name of the slice in various formats.
-
#slices ⇒ SliceRegistrar
Returns the slice’s collection of nested slices.
-
#source_path ⇒ Pathname
Returns the slice’s root component directory, accounting for App as a special case.
-
#start(provider_name) ⇒ container
Starts a provider.
-
#stop(provider_name) ⇒ container
Stops a provider.
Instance Attribute Details
#autoloader ⇒ Zeitwerk::Loader (readonly)
Returns the slice’s autoloader.
Each slice has its own ‘Zeitwerk::Loader` autoloader instance, which is setup when the slice is prepared.
75 76 77 |
# File 'lib/hanami/slice.rb', line 75 def autoloader @autoloader end |
#container ⇒ Object (readonly)
Returns the slice’s container.
This is a ‘Dry::System::Container` that is already configured for the slice.
In ordinary usage, you shouldn’t need direct access the container at all, since the slice provides its own methods for interacting with the container (such as #[], #keys, #key? #register, #register_provider, #prepare, #start, #stop).
If you need to configure the container directly, use #prepare_container.
91 92 93 |
# File 'lib/hanami/slice.rb', line 91 def container @container end |
#parent ⇒ Hanami::Slice (readonly)
Returns the slice’s parent.
For top-level slices defined in ‘slices/` or `config/slices/`, this will be the Hanami app itself (`Hanami.app`). For nested slices, this will be the slice in which they were registered.
62 63 64 |
# File 'lib/hanami/slice.rb', line 62 def parent @parent end |
Instance Method Details
#[](key) ⇒ Object
634 635 636 |
# File 'lib/hanami/slice.rb', line 634 def [](...) container.[](...) end |
#app ⇒ Hanami::App
Returns the Hanami app.
99 100 101 |
# File 'lib/hanami/slice.rb', line 99 def app Hanami.app end |
#app? ⇒ Boolean
Returns true if the slice is Hanami.app
109 110 111 |
# File 'lib/hanami/slice.rb', line 109 def app? eql?(app) end |
#boot ⇒ self
Boots the slice.
This will prepare the slice (if not already prepared), start each of its providers, register all the slice’s components from its Ruby source files, and import components from any other slices. It will also boot any of the slice’s own registered nested slices. It will then freeze its container so no further components can be registered.
Call ‘boot` if you want to fully load a slice and incur all load time up front, such as when preparing an app to serve web requests. Booting slices is the approach taken when running Hanami’s standard Puma setup (see ‘config.ru`).
336 337 338 339 340 341 342 343 344 345 346 347 |
# File 'lib/hanami/slice.rb', line 336 def boot return self if booted? prepare container.finalize! slices.each(&:boot) @booted = true self end |
#booted? ⇒ Boolean
Returns true if the slice has been booted.
381 382 383 |
# File 'lib/hanami/slice.rb', line 381 def booted? !!@booted end |
#call(rack_env) ⇒ Array
806 807 808 809 810 811 812 813 814 815 816 817 |
# File 'lib/hanami/slice.rb', line 806 def call(...) if rack_app rack_app.call(...) else = if Hanami.bundled?("hanami-router") "Could not handle this rack request because no routes are defined" else "Could not handle this rack request because the hanami router gem is missing, please add it" end raise NoRoutesDefinedError, end end |
#config ⇒ Hanami::Config
Returns the slice’s config.
A slice’s config is copied from the app config at time of first access.
123 124 125 126 127 128 |
# File 'lib/hanami/slice.rb', line 123 def config @config ||= app.config.dup.tap do |slice_config| # Unset config from app that does not apply to ordinary slices slice_config.root = nil end end |
#configure_provider(*args, **kwargs, &block) ⇒ Object
543 544 545 |
# File 'lib/hanami/slice.rb', line 543 def configure_provider(*args, **kwargs, &block) container.register_provider(*args, **kwargs, from: :hanami, &block) end |
#environment(env_name) ⇒ self #environment(env_name) {|slice| ... } ⇒ self
Evaluates the block for a given app environment only.
If the given ‘env_name` matches Hanami.env, then the block will be evaluated in the context of `self` (the slice) via `instance_eval`. The slice is also passed as the block’s optional argument.
If the env does not match, then the block is not evaluated at all.
160 161 162 163 |
# File 'lib/hanami/slice.rb', line 160 def environment(env_name, &block) instance_eval(&block) if env_name == config.env self end |
#export(keys) ⇒ self
Specifies the components to export from the slice.
Slices importing from this slice can import the specified components only.
663 664 665 666 |
# File 'lib/hanami/slice.rb', line 663 def export(keys) container.config.exports = keys self end |
#import(from:, as: nil, keys: nil) ⇒ Object
701 702 703 704 705 706 707 708 709 710 711 712 713 714 |
# File 'lib/hanami/slice.rb', line 701 def import(from:, **kwargs) slice = self container.after(:configure) do if from.is_a?(Symbol) || from.is_a?(String) slice_name = from from = slice.parent.slices[from.to_sym].container end as = kwargs[:as] || slice_name import(from: from, as: as, **kwargs) end end |
#inflector ⇒ Dry::Inflector
Returns the slice’s configured inflector.
Unless explicitly re-configured for the slice, this will be the app’s inflector.
248 249 250 |
# File 'lib/hanami/slice.rb', line 248 def inflector config.inflector end |
#key?(key) ⇒ Boolean
595 596 597 |
# File 'lib/hanami/slice.rb', line 595 def key?(...) container.key?(...) end |
#keys ⇒ Array<String>
Returns an array of keys for all currently registered components in the container.
For a prepared slice, this will be the set of components that have been previously resolved. For a booted slice, this will be all components available for the slice.
615 616 617 |
# File 'lib/hanami/slice.rb', line 615 def keys container.keys end |
#namespace ⇒ Module
Returns the constant for the slice’s module namespace.
187 188 189 |
# File 'lib/hanami/slice.rb', line 187 def namespace slice_name.namespace end |
#prepare ⇒ self #prepare(provider_name) ⇒ self
281 282 283 284 285 286 287 288 289 |
# File 'lib/hanami/slice.rb', line 281 def prepare(provider_name = nil) if provider_name container.prepare(provider_name) else prepare_slice end self end |
#prepare_container {|container| ... } ⇒ self
Captures the given block to be called with the slice’s container during the slice’s ‘prepare` step, after the slice has already configured the container.
This is intended for advanced usage only and should not be needed for ordinary slice configuration and usage.
314 315 316 317 |
# File 'lib/hanami/slice.rb', line 314 def prepare_container(&block) @prepare_container_block = block self end |
#prepared? ⇒ Boolean
Returns true if the slice has been prepared.
369 370 371 |
# File 'lib/hanami/slice.rb', line 369 def prepared? !!@prepared end |
#rack_app ⇒ #call?
Returns a [Rack] app for the slice, or nil if no routes are defined.
The rack app will be memoized on first access.
[rack]: github.com/rack/rack
784 785 786 787 788 |
# File 'lib/hanami/slice.rb', line 784 def rack_app return unless router @rack_app ||= router.to_rack_app end |
#register(key, object) ⇒ container #register(key, memoize: false, &block) ⇒ container #register(key, call: true, &block) ⇒ container
Registers a component in the slice’s container.
473 474 475 |
# File 'lib/hanami/slice.rb', line 473 def register(...) container.register(...) end |
#register_provider(name, namespace: nil, from: nil, source: nil) ⇒ container
537 538 539 |
# File 'lib/hanami/slice.rb', line 537 def register_provider(...) container.register_provider(...) end |
#register_slice(name) {|slice| ... } ⇒ slices #register_slice(name, slice_class) ⇒ slices
425 426 427 |
# File 'lib/hanami/slice.rb', line 425 def register_slice(...) slices.register(...) end |
#registered? ⇒ Boolean
Required for the slice to act as a provider target
602 603 604 |
# File 'lib/hanami/slice.rb', line 602 def registered?(...) container.registered?(...) end |
#relative_source_path ⇒ Pathname
Returns the slice’s root component directory, as a path relative to the app’s root.
233 234 235 |
# File 'lib/hanami/slice.rb', line 233 def relative_source_path source_path.relative_path_from(app.root) end |
#resolve ⇒ Object
642 643 644 |
# File 'lib/hanami/slice.rb', line 642 def resolve(...) container.resolve(...) end |
#root ⇒ Pathname
Returns the slice’s root, either the root as explicitly configured, or a default fallback of the slice’s name within the app’s ‘slices/` dir.
200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/hanami/slice.rb', line 200 def root # Provides a best guess for a root when it is not yet configured. # # This is particularly useful for user-defined slice classes that access `settings` inside # the class body (since the root needed to find the settings file). In this case, # `configuration.root` may be nil when `settings` is called, since the root is configured by # `SliceRegistrar#configure_slice` _after_ the class is loaded. # # In common cases, this best guess will be correct since most Hanami slices will be expected # to live in the app SLICES_DIR. For advanced cases, the correct slice root should be # explicitly configured at the beginning of the slice class body, before any calls to # `settings`. config.root || app.root.join(SLICES_DIR, slice_name.to_s) end |
#router(inspector: nil) ⇒ Hanami::Slice::Router?
Returns the slice’s router, if or nil if no routes are defined.
An optional ‘inspector`, implementing the `Hanami::Router::Inspector` interface, may be provided at first call (the router is then memoized for subsequent accesses). An inspector is used by the `hanami routes` CLI comment to provide a list of available routes.
The returned router is a Router, which provides all ‘Hanami::Router` functionality, with the addition of support for slice mounting with the Router#slice.
763 764 765 766 767 768 769 |
# File 'lib/hanami/slice.rb', line 763 def router(inspector: nil) raise SliceLoadError, "#{self} must be prepared before loading the router" unless prepared? @_mutex.synchronize do @_router ||= load_router(inspector: inspector) end end |
#routes ⇒ Hanami::Routes?
Returns the slice’s routes, or nil if no routes are defined.
You can define your routes in ‘config/routes.rb`.
742 743 744 745 746 |
# File 'lib/hanami/slice.rb', line 742 def routes return @routes if instance_variable_defined?(:@routes) @routes = load_routes end |
#settings ⇒ Hanami::Settings?
Returns the slice’s settings, or nil if no settings are defined.
You can define your settings in ‘config/settings.rb`.
726 727 728 729 730 |
# File 'lib/hanami/slice.rb', line 726 def settings return @settings if instance_variable_defined?(:@settings) @settings = Settings.load_for_slice(self) end |
#shutdown ⇒ self
Shuts down the slice’s providers, as well as the providers in any nested slices.
355 356 357 358 359 |
# File 'lib/hanami/slice.rb', line 355 def shutdown slices.each(&:shutdown) container.shutdown! self end |
#slice_name ⇒ SliceName
Returns a Hanami::SliceName for the slice, an object with methods returning the name of the slice in various formats.
172 173 174 |
# File 'lib/hanami/slice.rb', line 172 def slice_name @slice_name ||= SliceName.new(self, inflector: method(:inflector)) end |
#slices ⇒ SliceRegistrar
Returns the slice’s collection of nested slices.
393 394 395 |
# File 'lib/hanami/slice.rb', line 393 def slices @slices ||= SliceRegistrar.new(self) end |
#source_path ⇒ Pathname
Returns the slice’s root component directory, accounting for App as a special case.
221 222 223 |
# File 'lib/hanami/slice.rb', line 221 def source_path app? ? root.join(APP_DIR) : root end |
#start(provider_name) ⇒ container
561 562 563 |
# File 'lib/hanami/slice.rb', line 561 def start(...) container.start(...) end |
#stop(provider_name) ⇒ container
579 580 581 |
# File 'lib/hanami/slice.rb', line 579 def stop(...) container.stop(...) end |