How to use entries?
How to create an entry?
There are two ways to do it - block and method forms.
This is how it can be done using the block form.
module Features
class Gemfile
include ConvenientService::Feature::Standard::Config
entry :format do
Services::Format.result(path: "#{::Dir.pwd}/Gemfile")
end
end
end
The following code snippet demonstrates the equivalent method form.
module Features
class Gemfile
include ConvenientService::Feature::Standard::Config
entry :format
def format
Services::Format.result(path: "#{::Dir.pwd}/Gemfile")
end
end
end
How to define arguments for entries?
Since entries are built on the top of the regular Ruby blocks and methods you are able to utilize the techniques that you already know.
Here are some examples of how to define positional and keyword arguments.
The block form:
module Features
class Gemfile
include ConvenientService::Feature::Standard::Config
entry :format do |path, verbose: false|
Services::Format.result(path: path, verbose: verbose)
end
end
end
The method form:
module Features
class Gemfile
include ConvenientService::Feature::Standard::Config
entry :format
def format(path, verbose: false)
Services::Format.result(path: path, verbose: verbose)
end
end
end
Entries with variable arguments list may look like as follows.
The block form:
module Features
class Gemfile
include ConvenientService::Feature::Standard::Config
entry :format do |*args, **kwargs, &block|
path = args.first
verbose = block ? block.call : kwargs[:verbose]
Services::Format.result(path: path, verbose: verbose)
end
end
end
The method form:
module Features
class Gemfile
include ConvenientService::Feature::Standard::Config
entry :format
def format(*args, **kwargs, &block)
path = args.first
verbose = block ? block.call : kwargs[:verbose]
Services::Format.result(path: path, verbose: verbose)
end
end
end
How to invoke an entry?
No matter whether an entry was defined by a block or by a method, its invocation is the same, e.g:
Features::Gemfile.format
Features::Gemfile.format(path, verbose: true)
Features::Gemfile.format(*args, **kwargs, &block)
How to add a middleware for all entries?
Check the following feature.
module Features
class SomeFeature
include ConvenientService::Feature::Standard::Config
entry :some_entry_without_arguments
entry :some_entry_with_arguments
def some_entry_without_arguments
puts "Entry `some_entry_without_arguments` called."
end
def some_entry_with_arguments(*args, **kwargs, &block)
puts "Entry `some_entry_with_arguments` called."
end
end
end
It has two entries that are displaying some text on the screen.
For example:
Features::SomeFeature.some_entry_without_arguments
# "Entry `some_entry_without_arguments` called."
# => nil
Features::SomeFeature.some_entry_with_arguments
# "Entry `some_entry_with_arguments` called."
# => nil
Now, let's define a simple middleware.
class TestMiddleware < ConvenientService::MethodMiddleware
def next(entry_name, *args, **kwargs, &block)
puts "`TestMiddleware` called for entry `#{entry_name}` with args `#{args.inspect}`, kwargs `#{kwargs.inspect}` and block `#{block.inspect}`."
chain.next(entry_name, *args, **kwargs, &block)
end
end
It logs the entry name and its arguments.
Then it triggers the original entry behaviour.
In order to register a middleware for all entries inside the particular feature, use the middlewares :entry
directive.
module Features
class SomeFeature
include ConvenientService::Feature::Standard::Config
middlewares :entry do
use TestMiddleware
end
entry :some_entry_without_arguments
entry :some_entry_with_arguments
def some_entry_without_arguments
puts "Entry `some_entry_without_arguments` called."
end
def some_entry_with_arguments(*args, **kwargs, &block)
puts "Entry `some_entry_with_arguments` called."
end
end
end
Now the TestMiddleware
is executed before any entry invocation.
This is how it looks in practice.
Features::SomeFeature.some_entry_without_arguments
# "`TestMiddleware` called for entry `some_entry_without_arguments` with args `[]`, kwargs `{}` and block `nil`."
# "Entry `some_entry_without_arguments` called."
# => nil
Features::SomeFeature.some_entry_with_arguments(:foo, foo: :bar) { :foo }
# "`TestMiddleware` called for entry `some_entry_with_arguments` with args `[:foo]`, kwargs `{:foo=>:bar}` and block `#<Proc:0x00000001227756c8.>`."
# "Entry `some_entry_with_arguments` called."
# => nil
How to add a middleware for the specific entry?
The process is almost the same as with the addition of a middleware for all entries.
But the arguments list does not start with positional entry_name
.
It is still possible to access entry_name
via method method
🙂.
class TestMiddleware < ConvenientService::MethodMiddleware
def next(*args, **kwargs, &block)
puts "`TestMiddleware` called for entry `#{method}` with args `#{args.inspect}`, kwargs `#{kwargs.inspect}` and block `#{block.inspect}`."
chain.next(*args, **kwargs, &block)
end
end
The registration directive contains the specific entry name.
module Features
class SomeFeature
include ConvenientService::Feature::Standard::Config
middlewares :some_entry do
use TestMiddleware
end
entry :some_entry
entry :some_other_entry
def some_entry(first_positional_argument, second_positional_argument)
puts "Entry `some_entry` called."
end
def some_other_entry
puts "Entry `some_other_entry` called."
end
end
end
Thus the TestMiddleware
is executed only before specific entry invocation.
Features::SomeFeature.some_entry(:foo, :bar)
# "`TestMiddleware` called for entry `some_entry` with args `[:foo, :bar]`, kwargs `{}` and block `nil`."
# "Entry `some_entry` called."
# => nil
All the other entries stay unaffected.
Features::SomeFeature.some_other_entry
# "Entry `some_other_entry` called."
# => nil