• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

lib/Module/H24-Aug-2014-291107

t/H24-Aug-2014-930681

ChangesH A D24-Aug-20141.4 KiB5529

INSTALLH A D24-Aug-20141,017 4524

LICENSEH A D24-Aug-20148.8 KiB208154

MANIFESTH A D24-Aug-2014684 3736

META.jsonH A D24-Aug-201420 KiB622620

META.ymlH A D24-Aug-201412.8 KiB455454

Makefile.PLH A D24-Aug-20141.6 KiB7658

README.mdH A D24-Aug-20144.1 KiB13283

dist.iniH A D24-Aug-2014284 1512

README.md

1# NAME
2
3Module::Implementation - Loads one of several alternate underlying implementations for a module
4
5# VERSION
6
7version 0.09
8
9# SYNOPSIS
10
11    package Foo::Bar;
12
13    use Module::Implementation;
14
15    BEGIN {
16        my $loader = Module::Implementation::build_loader_sub(
17            implementations => [ 'XS',  'PurePerl' ],
18            symbols         => [ 'run', 'check' ],
19        );
20
21        $loader->();
22    }
23
24    package Consumer;
25
26    # loads the first viable implementation
27    use Foo::Bar;
28
29# DESCRIPTION
30
31This module abstracts out the process of choosing one of several underlying
32implementations for a module. This can be used to provide XS and pure Perl
33implementations of a module, or it could be used to load an implementation for
34a given OS or any other case of needing to provide multiple implementations.
35
36This module is only useful when you know all the implementations ahead of
37time. If you want to load arbitrary implementations then you probably want
38something like a plugin system, not this module.
39
40# API
41
42This module provides two subroutines, neither of which are exported.
43
44## Module::Implementation::build\_loader\_sub(...)
45
46This subroutine takes the following arguments.
47
48- implementations
49
50    This should be an array reference of implementation names. Each name should
51    correspond to a module in the caller's namespace.
52
53    In other words, using the example in the ["SYNOPSIS"](#synopsis), this module will look
54    for the `Foo::Bar::XS` and `Foo::Bar::PurePerl` modules.
55
56    This argument is required.
57
58- symbols
59
60    A list of symbols to copy from the implementation package to the calling
61    package.
62
63    These can be prefixed with a variable type: `$`, `@`, `%`, `&`, or
64    `*)`. If no prefix is given, the symbol is assumed to be a subroutine.
65
66    This argument is optional.
67
68This subroutine _returns_ the implementation loader as a sub reference.
69
70It is up to you to call this loader sub in your code.
71
72I recommend that you _do not_ call this loader in an `import()` sub. If a
73caller explicitly requests no imports, your `import()` sub will not be run at
74all, which can cause weird breakage.
75
76## Module::Implementation::implementation\_for($package)
77
78Given a package name, this subroutine returns the implementation that was
79loaded for the package. This is not a full package name, just the suffix that
80identifies the implementation. For the ["SYNOPSIS"](#synopsis) example, this subroutine
81would be called as `Module::Implementation::implementation_for('Foo::Bar')`,
82and it would return "XS" or "PurePerl".
83
84# HOW THE IMPLEMENTATION LOADER WORKS
85
86The implementation loader works like this ...
87
88First, it checks for an `%ENV` var specifying the implementation to load. The
89env var is based on the package name which loads the implementations. The
90`::` package separator is replaced with `_`, and made entirely
91upper-case. Finally, we append "\_IMPLEMENTATION" to this name.
92
93So in our ["SYNOPSIS"](#synopsis) example, the corresponding `%ENV` key would be
94`FOO_BAR_IMPLEMENTATION`.
95
96If this is set, then the loader will **only** try to load this one
97implementation.
98
99If the env var requests an implementation which doesn't match one of the
100implementations specified when the loader was created, an error is thrown.
101
102If this one implementation fails to load then loader throws an error. This is
103useful for testing. You can request a specific implementation in a test file
104by writing something like this:
105
106    BEGIN { $ENV{FOO_BAR_IMPLEMENTATION} = 'XS' }
107    use Foo::Bar;
108
109If the environment variable is _not_ set, then the loader simply tries the
110implementations originally passed to `Module::Implementation`. The
111implementations are tried in the order in which they were originally passed.
112
113The loader will use the first implementation that loads without an error. It
114will copy any requested symbols from this implementation.
115
116If none of the implementations can be loaded, then the loader throws an
117exception.
118
119The loader returns the name of the package it loaded.
120
121# AUTHOR
122
123Dave Rolsky <autarch@urth.org>
124
125# COPYRIGHT AND LICENSE
126
127This software is Copyright (c) 2014 by Dave Rolsky.
128
129This is free software, licensed under:
130
131    The Artistic License 2.0 (GPL Compatible)
132