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][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
preparestep, after the slice has already configured the container. -
#prepared? ⇒ Boolean
Returns true if the slice has been prepared.
-
#rack_app ⇒ #call?
Returns a [Rack][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.
-
#with_slices ⇒ Array<Hanami::Slice>
Returns an array of this slice and all of its nested slices.
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
654 655 656 |
# File 'lib/hanami/slice.rb', line 654 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
826 827 828 829 830 831 832 833 834 835 836 837 |
# File 'lib/hanami/slice.rb', line 826 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
563 564 565 |
# File 'lib/hanami/slice.rb', line 563 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.
683 684 685 686 |
# File 'lib/hanami/slice.rb', line 683 def export(keys) container.config.exports = keys self end |
#import(from:, as: nil, keys: nil) ⇒ Object
721 722 723 724 725 726 727 728 729 730 731 732 733 734 |
# File 'lib/hanami/slice.rb', line 721 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
615 616 617 |
# File 'lib/hanami/slice.rb', line 615 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.
635 636 637 |
# File 'lib/hanami/slice.rb', line 635 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.
804 805 806 807 808 |
# File 'lib/hanami/slice.rb', line 804 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.
493 494 495 |
# File 'lib/hanami/slice.rb', line 493 def register(...) container.register(...) end |
#register_provider(name, namespace: nil, from: nil, source: nil) ⇒ container
557 558 559 |
# File 'lib/hanami/slice.rb', line 557 def register_provider(...) container.register_provider(...) end |
#register_slice(name) {|slice| ... } ⇒ slices #register_slice(name, slice_class) ⇒ slices
445 446 447 |
# File 'lib/hanami/slice.rb', line 445 def register_slice(...) slices.register(...) end |
#registered? ⇒ Boolean
Required for the slice to act as a provider target
622 623 624 |
# File 'lib/hanami/slice.rb', line 622 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
662 663 664 |
# File 'lib/hanami/slice.rb', line 662 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.
783 784 785 786 787 788 789 |
# File 'lib/hanami/slice.rb', line 783 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.
762 763 764 765 766 |
# File 'lib/hanami/slice.rb', line 762 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.
746 747 748 749 750 |
# File 'lib/hanami/slice.rb', line 746 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
581 582 583 |
# File 'lib/hanami/slice.rb', line 581 def start(...) container.start(...) end |
#stop(provider_name) ⇒ container
599 600 601 |
# File 'lib/hanami/slice.rb', line 599 def stop(...) container.stop(...) end |
#with_slices ⇒ Array<Hanami::Slice>
Returns an array of this slice and all of its nested slices.
The nested slices are returned first (with their more specific namespaces ahead of their parents'), and this slice is returned last. This ordering means a class can be matched to its most specific slice by detecting the first slice whose namespace it belongs to. It is useful when you need to operate across every container, such as in test support code.
413 414 415 |
# File 'lib/hanami/slice.rb', line 413 def with_slices slices.with_nested + [self] end |