summaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2014-08-24 16:36:19 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2014-08-24 16:36:19 +0000
commitb808141b894ad538db75a7067e0199cbfe6337a9 (patch)
treeb3560724f86d6383c5ded5a79749c3f69592eb51 /README.md
downloadModule-Implementation-tarball-master.tar.gz
Module-Implementation-0.09HEADModule-Implementation-0.09master
Diffstat (limited to 'README.md')
-rw-r--r--README.md131
1 files changed, 131 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e1e1edd
--- /dev/null
+++ b/README.md
@@ -0,0 +1,131 @@
+# NAME
+
+Module::Implementation - Loads one of several alternate underlying implementations for a module
+
+# VERSION
+
+version 0.09
+
+# SYNOPSIS
+
+ package Foo::Bar;
+
+ use Module::Implementation;
+
+ BEGIN {
+ my $loader = Module::Implementation::build_loader_sub(
+ implementations => [ 'XS', 'PurePerl' ],
+ symbols => [ 'run', 'check' ],
+ );
+
+ $loader->();
+ }
+
+ package Consumer;
+
+ # loads the first viable implementation
+ use Foo::Bar;
+
+# DESCRIPTION
+
+This module abstracts out the process of choosing one of several underlying
+implementations for a module. This can be used to provide XS and pure Perl
+implementations of a module, or it could be used to load an implementation for
+a given OS or any other case of needing to provide multiple implementations.
+
+This module is only useful when you know all the implementations ahead of
+time. If you want to load arbitrary implementations then you probably want
+something like a plugin system, not this module.
+
+# API
+
+This module provides two subroutines, neither of which are exported.
+
+## Module::Implementation::build\_loader\_sub(...)
+
+This subroutine takes the following arguments.
+
+- implementations
+
+ This should be an array reference of implementation names. Each name should
+ correspond to a module in the caller's namespace.
+
+ In other words, using the example in the ["SYNOPSIS"](#synopsis), this module will look
+ for the `Foo::Bar::XS` and `Foo::Bar::PurePerl` modules.
+
+ This argument is required.
+
+- symbols
+
+ A list of symbols to copy from the implementation package to the calling
+ package.
+
+ These can be prefixed with a variable type: `$`, `@`, `%`, `&`, or
+ `*)`. If no prefix is given, the symbol is assumed to be a subroutine.
+
+ This argument is optional.
+
+This subroutine _returns_ the implementation loader as a sub reference.
+
+It is up to you to call this loader sub in your code.
+
+I recommend that you _do not_ call this loader in an `import()` sub. If a
+caller explicitly requests no imports, your `import()` sub will not be run at
+all, which can cause weird breakage.
+
+## Module::Implementation::implementation\_for($package)
+
+Given a package name, this subroutine returns the implementation that was
+loaded for the package. This is not a full package name, just the suffix that
+identifies the implementation. For the ["SYNOPSIS"](#synopsis) example, this subroutine
+would be called as `Module::Implementation::implementation_for('Foo::Bar')`,
+and it would return "XS" or "PurePerl".
+
+# HOW THE IMPLEMENTATION LOADER WORKS
+
+The implementation loader works like this ...
+
+First, it checks for an `%ENV` var specifying the implementation to load. The
+env var is based on the package name which loads the implementations. The
+`::` package separator is replaced with `_`, and made entirely
+upper-case. Finally, we append "\_IMPLEMENTATION" to this name.
+
+So in our ["SYNOPSIS"](#synopsis) example, the corresponding `%ENV` key would be
+`FOO_BAR_IMPLEMENTATION`.
+
+If this is set, then the loader will **only** try to load this one
+implementation.
+
+If the env var requests an implementation which doesn't match one of the
+implementations specified when the loader was created, an error is thrown.
+
+If this one implementation fails to load then loader throws an error. This is
+useful for testing. You can request a specific implementation in a test file
+by writing something like this:
+
+ BEGIN { $ENV{FOO_BAR_IMPLEMENTATION} = 'XS' }
+ use Foo::Bar;
+
+If the environment variable is _not_ set, then the loader simply tries the
+implementations originally passed to `Module::Implementation`. The
+implementations are tried in the order in which they were originally passed.
+
+The loader will use the first implementation that loads without an error. It
+will copy any requested symbols from this implementation.
+
+If none of the implementations can be loaded, then the loader throws an
+exception.
+
+The loader returns the name of the package it loaded.
+
+# AUTHOR
+
+Dave Rolsky <autarch@urth.org>
+
+# COPYRIGHT AND LICENSE
+
+This software is Copyright (c) 2014 by Dave Rolsky.
+
+This is free software, licensed under:
+
+ The Artistic License 2.0 (GPL Compatible)