NAME
    pkg - transparently use packages and inner packages

SYNOPSIS
      # standard operations
      # works on either inner or normal packages
      # -------------------------------       ----------------
      use pkg 'A';                       #=>  use A;
      use pkg 'A', 'a', 'b';             #=>  use A 'a', 'b';
      use pkg 'A', [];                   #=>  use A ();

      # extra operations

      # default alias for a class package
      use pkg -alias => 'A::B::C';
      C->new(...); #equivalent to A::B::C->new();

      # specific alias for a class package
      use pkg 'A::B::C' => -as => 'ABC';
      ABC->new( ); # equivalent to A:B::C->new;

      # multiple packages
      use pkg [ 'A::B::C' => -as => 'ABC'],
              [ 'A::B'    => -as => 'AB' ];

      # operate on A and its inner packages
      use pkg 'A', '-inner';

      # operate only on the inner packages of A
      use pkg 'A', '-only_inner';

      # operate on A and its inner packages, excluding anything below A::B
      use pkg 'A', -inner, -exclude => qr/^A::B::/;

DESCRIPTION
    pkg extends the standard "use" statement to more transparently handle
    inner packages, additionally incorporating some of the functionality of
    the aliased and use pragmata with a few extra twists.

    An inner package is one which does not have the same name as the (fully
    qualified) module in which it is defined. For example, if A.pm contains

      package A;

      sub a { ... }

      package A::B;

      sub ab { ... }

      package A::C;

      sub ac { ... }

      1;

    packages "A::B" and "A::C" are inner packages. The use statement (as
    well as most pragmata dealing with modules) does not handle inner
    packages. Some, such as parent, do, but require the user (via the
    "-norequire" option) to know if the package is inner or not.

    For example, after loading the above module:

      use A;

    You could simply call

      A::a();
      A::B::ab();
      A::C::ac();

    But, what if package A::B exported ab? Its import routine is not
    automatically called when A is loaded. If you try to do this

      use A::B 'ab';

    you'll get an error from Perl as it tries to search for a file named
    e.g., A/B.pm. It doesn't check to see if the "A::B" package has been
    loaded.

    Instead, you'd need to do this:

      A::B->import( 'ab' );
      ab();

    Or, using pkg:

      use pkg [ 'A' ], [ 'A::B' => qw[ ab ] ];

  Simple Usage
    In its simplest form, pkg accepts a *list* of a package name (*as a
    string*) and its imports.

      use pkg 'A::B', qw( funca funcb );

    This loads the package "A::B" (if necessary) and imports the functions
    funca and funcb. Note that if "A::B" is an inner package, the module
    (file) which contains it must be loaded prior to this e.g.

      # either of these is sufficient
      use A;
      use pkg 'A';

    This needs to be done only *once* (not every time an inner package is
    used). Of course it can be combined with loading "A::B":

      use pkg [ 'A' ], [ 'A::B' => qw( funca funcb ) ];

  Controlling imports
    There is a subtlety in how the standard use statement handles empty or
    non-existent import lists:

       use A;           # call A->import();
       use A 'a', 'b'   # call A->import( 'a', 'b' );
       use A ();        # do *not* call A->import;

    This mechanism isn't available to pkg as it cannot tell the difference
    between:

       use pkg 'A';
       use pkg 'A', ();

    Instead, use "[]" instead of "()":

       use pkg 'A', [];

    What if you need to pass a "[]" to "A->import()"? Use the "-import"
    package option:

      use pkg 'A', -import => [];        #=> use A [];
      use pkg 'A', -import => '-import'; #=> use A '-import';

    "-import" instructs pkg that all remaining arguments should be passed to
    the package's import routine.

    Note that the following are equivalent

      use A (), 'a';
      use pkg 'A', [], 'a';

    and result in

      A->import( 'a' );

  Multiple packages
    Multiple packages may be operated on by passing each package's
    specifications as separate array references:

      use pkg ['A'], ['A::B', qw( funca funcb ) ];

OPTIONS
    pkg accepts options to modify its behavior. "Global" options (which
    affect more than one package) can appear in multiple places if more than
    one package is manipulated. Package specific options always appear
    directly after the package name and apply only to that package.

    If there's only one package, the syntax is simple. Global options occur
    before the package name.

      use pkg -norequire => 'My::Package' -as => 'MyP';

    "-norequire" is a global option, and "-as" is a package option.

    If more than one package is specified, global options may occur both
    outside of the package specifications as well as inside of them. For
    example,

      use pkg
        -alias =>
        [ 'My::FirstClass' ],
        [ -noalias => 'My::SecondClass' ]
        [ 'My::ThirdClass' => -as => 'ThirdClassIsBetterThanFirst' ]
        -noalias =>
        [ 'My::Library1' ],
        [ 'My::Library2' ],
        [ 'My::Library3' ],
        ;

    The options appearing outside of the package specifications affect all
    packages which follow. The options inside a specification affect that
    package only. As shown, some options may be negated, and package options
    may override global ones.

  Global Options
    "-alias"
    "-noalias"
        Provide (or don't provide) shortened names for class names. These
        are simply the last component of the original name.

        The idea is borrowed from the "aliased" pragma; pkg constructs and
        exports a subroutine with the shortened name which returns the fully
        qualified name.

        For example,

          use pkg -alias => 'A::Long:Class';

          # these are equivalent
          A::Long::Class->new();
          Class->new();

        If multiple classes are loaded, no checks are performed to ensure
        that the shortened names are unique. Use the "-as" package option to
        specify specific names.

    "-strip"
        Created aliases by removing a prefix from the succeeding class
        names. The prefix may be specified in one of two ways:

        "-strip" *string*
            Remove a leading *string* from the class names. All component
            separators ("::") are also removed. For example,

              -strip => 'A::C', 'A::C::E::F::G'

            results in an alias of "EFG".

        "-strip { pfx => *string*, sep => *string* }"
            Remove *prefix* from class names, and replace the class
            component separators ("::") with the specified string. After
            prefix removal, a leading "::" sequence is removed.

    "-require"
    "-norequire"
        Try to load (or don't try to load) the packages with
        Class::Load::load_class. If you know that the package is an inner
        package and the file containing it has already been loaded,
        specifying "-norequire" can speed things up by not loading
        Class::Load.

        By default packages are loaded (i.e. "-require").

  Package Options
    "-as" => *string*
        Create an alias named *string* for the package. The aliased name
        must be a legal subroutine name.

        For example,

          use pkg 'A::Long:Class' => -as => 'ALC';

          # these are equivalent
          A::Long::Class->new();
          ALC->new();

    "-import"
        There's always a chance that a package's import list may be confused
        with pkg package options (perhaps it also has a "-as" option). To
        avoid this, a package's import list may be preceded with the
        "-import" option, which indicates to pkg that all of the following
        arguments are to be passed as is to the package's import routine.

          # these are equivalent
          use A ( '-as', 'func1', 'func2' );
          use pkg 'A' => -import => ( '-as', 'func1', 'func2' );

    "-require"
    "-norequire"
        This has the same functionality as the similarly named global
        options, but as a package option may be placed after the package
        name for aesthetics.

    "-inner"
        In addition to the package, process any of its currently loaded
        inner packages. Inner packages are discovered via
        Devel::InnerPackage, and must fall within the "hierarchy" of the
        package. For example, given a module with the following contents:

          package A;
          sub a {}

          package A::B;
          sub ab {}

          package B;
          sub b {}

        "A::B" is an inner package of "A", but "B" is not. Inner packages
        must have defined symbols, otherwise they will not be identified.

    "-only_inner"
        Similar to "-inner", but *only* the inner packages are processed,
        not the package itself.

        This *does not* affect whether the package is loaded; this is
        controlled by the "-require" option.

    "-include" *specification*
        Check the package name against the *specification* using the smart
        match operator ("~~") and ignore it if it does not match. If
        "-inner" or "-only_inner" are specified, inner packages are also
        checked.

        This *does not* affect whether the package is loaded; this is
        controlled by the "-require" option.

        This is most useful when either "-inner" or "-only_inner" is
        specified.

    "-exclude" *specification*
        Check the package name against the *specification* using the smart
        match operator ("~~") and ignore it if it matches. The "-exclude"
        match is processed after "-include" if both are specified. If
        "-inner" or "-only_inner" are specified, inner packages are also
        checked.

        This *does not* affect whether the package is loaded; this is
        controlled by the "-require" option.

        This is most useful when either "-inner" or "-only_inner" is
        specified.

    "-version" => *version*
        Specify the minimum acceptable version of the package.

DIAGNOSTICS
    "global option '%s': unknown option"
        The specified option wasn't recognized as a global option.

    "package option '%s': unknown option"
        The specified option wasn't recognized as a package option.

    "option '%s': cannot be negated"
        An illegal negation of the specified option was specified.

    "option '%s': not enough values"
        The specified option required more values than was specified.

    "can't use option "%s" when looping over inner packages"
        The specifed option cannot be used in conjunction with "-inner" or
        "-only_inner".

    "-strip: no prefix specified"
        The "-strip" option requires an argument specifying the prefix to
        remove.

    "internal error"
        Something really bad happened.

IMPLEMENTATION
    pkg does very little on its own. It uses the following modules:

    Class::Load
        Class::Load::load_class is used to load the package. It also takes
        care of checking package versions.

    Import::Into
        This is used to call a package's import routine

    aliased
        This provided the inspiration for the aliasing implementation.

    Devel::InnerPackages
        Discover a package's inner self.

DEPENDENCIES
    Class::Load, Import::Into, Devel::InnerPackages, Perl 5.10.1.

INCOMPATIBILITIES
    None reported.

BUGS AND LIMITATIONS
    pkg is focussed specifically on dealing with packages and is not
    intended as a general purpose replacement for the standard use
    statement. In particular it does not know how to deal with other
    pragmata, e.g.,

      use pkg strict;

    will probably not do anything useful and will most probably advance the
    heat death of the universe.

    Please report any bugs or feature requests to "bug-pkg@rt.cpan.org", or
    through the web interface at
    <http://rt.cpan.org/Public/Dist/Display.html?Name=pkg>.

SEE ALSO
    aliased, namespace, as, use.

VERSION
    Version 0.01

LICENSE AND COPYRIGHT
    Copyright (c) 2013 Diab Jerius

    pkg is free software: you can redistribute it and/or modify it under the
    terms of the GNU General Public License as published by the Free
    Software Foundation, either version 3 of the License, or (at your
    option) any later version.

    This program is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
    Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program. If not, see <http://www.gnu.org/licenses/>.

AUTHOR
    Diab Jerius <djerius@cpan.org>

