Module: Toys::Mixin

Overview

A mixin definition. Mixin modules should include this module.

A mixin is a collection of methods that are available to be called from a tool implementation (i.e. its run method). The mixin is added to the tool class, so it has access to the same methods that can be called by the tool, such as Context#get.

Usage

To create a mixin, define a module, and include this module. Then define the methods you want to be available.

If you want to perform some initialization specific to the mixin, you can provide an initializer block and/or an inclusion block. These can be specified by calling the module methods defined in ModuleMethods.

The initializer block is called when the tool context is instantiated in preparation for execution. It has access to context methods such as Context#get, and can perform setup for the tool execution itself, such as initializing some persistent state and storing it in the tool using Context#set. The initializer block is passed any extra arguments that were provided to the include directive. Define the initializer by calling ModuleMethods#on_initialize.

The inclusion block is called in the context of your tool class when your mixin is included. It is also passed any extra arguments that were provided to the include directive. It can be used to issue directives to define tools or other objects in the DSL, or even enhance the DSL by defining DSL methods specific to the mixin. Define the inclusion block by calling ModuleMethods#on_include.

Example

This is an example that implements a simple counter. Whenever the counter is incremented, a log message is emitted. The tool can also retrieve the final counter value.

# Define a mixin by creating a module that includes Toys::Mixin
module MyCounterMixin
  include Toys::Mixin

  # Initialize the counter. Notice that the initializer is evaluated
  # in the context of the runtime context, so has access to the runtime
  # context state.
  on_initialize do |start = 0|
    set(:counter_value, start)
  end

  # Mixin methods are evaluated in the runtime context and so have
  # access to the runtime context state, just as if you had defined
  # them in your tool.
  def counter_value
    get(:counter_value)
  end

  def increment
    set(:counter_value, counter_value + 1)
    logger.info("Incremented counter")
  end
end

Now we can use it from a tool:

tool "count-up" do
  # Pass 1 as an extra argument to the mixin initializer
  include MyCounterMixin, 1

  def run
    # Mixin methods can be called.
    5.times { increment }
    puts "Final value is #{counter_value}"
  end
end

Defined Under Namespace

Modules: ModuleMethods

Class Method Summary collapse

Class Method Details

.create(&block) ⇒ Class

Create a mixin module with the given block.

Parameters:

  • block (Proc)

    Defines the mixin module.

Returns:

  • (Class)


87
88
89
90
91
92
93
# File 'lib/toys/mixin.rb', line 87

def self.create(&block)
  mixin_mod = ::Module.new do
    include ::Toys::Mixin
  end
  mixin_mod.module_eval(&block) if block
  mixin_mod
end