NAME

Evented::API::Module - represents a module for use with Evented::API::Engine.

SYNOPSIS

# Module metadata
#
# @name:        'My::Module'
# @package:     'M::My::Module'
# @description:
#
# @depends.modules+ 'Some::Other'
# @depends.modules+ 'Another::Yet'
#
# @author.name:     'Mitchell Cooper'
# @author.website:  'https://github.com/cooper'
#
package M::My::Module;

use warnings;
use strict;
use 5.010;

# Auto-exported variables
our ($api, $mod);

# Default initializer
sub init {
    say 'Loading ', $mod->name;
    
    # indicates load success
    return 1;
}

# Default deinitializer
sub void {
    say 'Bye!';
    
    # indicates unload success
    return 1;
}

# Package must return module object
$mod;

DESCRIPTION

Module directory structure

Modules must be placed within one of the search directories specified in the Evented:API::Engine mod_inc consturctor option or the dirs option of ->load_module and similar Engine methods.

A module in its simplest form is a directory with the .module extension and a single .pm file of the same name. Double-colon namespace separators are condensed to directories, as with normal Perl packages. For instance, a module called My::Backend's main package file could be located at either of the following:

$SEARCH_DIR/My/Backend.module/Backend.pm
$SEARCH_DIR/My/Backend/Backend.module/Backend.pm

The directory with the .module extension is called the module directory. In addition to the Perl package file, it can house other data associated with the module, such as JSON-encoded metadata, submodules, and documentation.

$MODULE_DIR/Backend.pm              # package file
$MODULE_DIR/Backend.json            # metadata file
$MODULE_DIR/Backend.md              # documentation
$MODULE_DIR/More.module/More.pm     # submodule package
$MODULE_DIR/More.module/More.json   # submodule metadata

Module metadata

Module metadata is extracted from comments in primary package file.

Metadata is written to a .json file within the module directory (when developer mode is enabled). These metadata files should be included in distributions, as they contains version and author information.

Syntax for metadata comments is as follows:

# @normal:      "A normal option with a Perl-encoded value"
# @boolean      # a boolean option!
# @list+        'A value to add to a list'
# @list+        'Another value to add to the list'

Supported options

# @name:                'Some::Module'              # module name
# @package:             'M::Some::Module'           # main package
# @package+             'M::Some::Module::Blah'     # additional packages
# @version:             '1.01'                      # module version
# @depends.modules+     'Some::Mod::Dependency'     # module dependencies
# @depends.modules+     'A::B', 'C::D'              # additional dependencies
# @depends.bases+       'Some::Base::Dependency'    # base dependencies
# @author.name:         'John Doe'                  # author name
# @author.website:      'http://john.example.com'   # author URL
# @no_bless                                         # don't bless
# @preserve_sym                                     # don't erase symbols

These, I feel, require additional explanation:

  • @version - this obviously is a numerical module version. I'm mentioning it here to tell you that you probably shouldn't bother using it, as the API Engine offers automatic versioning (with developer mode enabled) if you simply omit this option.

  • @depends.bases - like @depends.modules, except the Base:: prefix is added. bases are modules which don't really offer any functionality on their own but provide APIs for other modules to use.

  • @no_bless - if true, the module object will not be blessed to the module's primary package (which is the default behavior). this might be useful if your module contains names conflicting with API Engine or uses autoloading.

  • @preserve_sym - if true, the packages associated with the module will not be deleted from the symbol table upon unload. this is worse for memory, but it may be necessary for the "guts" of your program, particularly those parts which deal with the loading and unloading of modules themselves.

METHODS

$mod->name

Returns module full name.

$mod->package

Returns module's primary Perl package name.

$mod->packages

Returns all packages associate with module.

$mod->api

Returns associated API Engine .

$mod->parent

Returns parent module, if this is a submodule.

$mod->submodules

Returns list of loaded submodules objects.

$mod->Log($msg)

Used for logging associated with module. Use API Engine ->Log() for messages not associated with a specific module.

Parameters

  • $msg - text to log.

$mod->get_symbol($sym)

Fetches the value of a symbol in module's main package.

Parameters

  • $sym - string symbol; such as @list, %hash, or $scalar.

Returns

The data in its native type (NOT a reference), or the zero value for that type if no symbol table entry exists.

$mod->load_submodule($submod_name)

Loads a submodule.

This is generally used within the module initializer.

Parameters

  • $submod_name - name of the submodule, without the parent module name prefix. for instance if the full submodule name is My::Module::Sub, this is simply Sub.

Returns

Submodule object on success, false otherwise.

$mod->unload_submodule($submod)

Unloads a submodule.

You do not have to call this in the parent module deinitializer. Only use this method if you want to dynamically unload a submodule for some reason without unloading the parent module.

Parameters

  • $submod - submodule object or name, without the parent module name prefix. for instance if the full submodule name is My::Module::Sub, this is simply Sub.

$mod->add_companion_submodule($mod_name, $submod_name)

Registers a submodule (provided by this module) as a companion of another top-level module.

Companion submodules are submodules which are automatically loaded and unloaded as needed in conjunction with other top-level modules.

This is generally called from within the parent module initializer.

Parameters

  • $mod_name - name of another top-level module to register the submodule as a companion.

  • $submod_name - name of the submodule to register a companion, without the parent module name prefix. for instance if the full submodule name is My::Module::Sub, this is simply Sub.

$mod->store($key, $value)

Stores a piece of data associated with module.

Parameters

  • $key - name for fetching data later.

  • $value - value to store.

$mod->retrieve($key, $default_value)

Retrieves a piece of data associated with module.

Parameters

  • $key - name associated with data to fetch.

Returns

Fetched data, undef if not found.

$mod->list_store_add($key, $value)

Adds an entry to a list of data associated with module.

  • $key - name for fetching data later.

  • $value - value to add.

$mod->list_store_remove_matches($key, $code, $max)

Removes entries satisfying a code from a list of data associated with module.

Parameters

  • $key - name of list.

  • $code - code reference passed each entry which should return true for matches.

  • $max - optional, maximum number of entries to remove.

Returns

Number of items removed, false if none matched.

$mod->list_store_items($key)

Fetches all values in a list associated with module.

  • $key - name of the list to retrieve.

Returns

List of fetch values, or empty list if none were found.

$mod->dependencies

Returns top-level module dependencies.

$mod->companions

For companion submodules, Returns modules that this submodule depends on.

$mod->dependents

Returns top-level modules that depend on this module.

$mod->dependent_companions

Returns companion submodules that depend on this module.

AUTHOR

Mitchell Cooper <cooper@cpan.org>

Copyright © 2017. Released under New BSD license.

Comments, complaints, and recommendations are accepted. Bugs may be reported on GitHub.