NAME
    MooX::Press - quickly create a bunch of Moo/Moose/Mouse classes and roles

SYNOPSIS
      package MyApp;
      use Types::Standard qw(Str Num);
      use MooX::Press (
        role => [
          'Livestock',
          'Pet',
          'Milkable' => {
            can => [
              'milk' => sub { print "giving milk\n"; },
            ],
          },
        ],
        class => [
          'Animal' => {
            has => [
              'name'   => Str,
              'colour',
              'age'    => Num,
              'status' => { enum => ['alive', 'dead'], default => 'alive' },
            ],
            subclass => [
              'Panda',
              'Cat'  => { with => ['Pet'] },
              'Dog'  => { with => ['Pet'] },
              'Cow'  => { with => ['Livestock', 'Milkable'] },
              'Pig'  => { with => ['Livestock'] },
            ],
          },
        ],
      );

    Using your classes:

      use MyApp;
  
      my $kitty = MyApp->new_cat(name => "Grey", status => "alive");
      # or:       MyApp::Cat->new(name => "Grey", status => "alive");
  
      MyApp->new_cow(name => "Daisy")->milk();

    I realize this is a longer synopsis than most CPAN modules give, but
    considering it sets up six classes and three roles with some attributes
    and methods, applies the roles to the classes, and creates a type library
    with nine types in it, it's pretty concise.

DESCRIPTION
    MooX::Press (pronounced "Moo Express") is a quick way of creating a bunch
    of simple Moo classes and roles at once without needing to create separate
    Perl modules for each class and each role, and without needing to add a
    bunch of boilerplate to each file.

    It also supports Moose and Mouse, though Moo classes and roles play nicely
    with Moose (and to a certain extent with Mouse) anyway.

  Import Options
    MooX::Press is called like:

      use MooX::Press %import_opts;

    The following options are supported. To make these easier to remember,
    options follow the convention of using lower-case singular, and reusing
    keywords from Perl and Moo/Moose/Mouse when possible.

    `class` *(OptList)*
        This is the list of classes to create as an optlist. An optlist is an
        arrayref of strings, where each string is optionally followed by a
        reference.

          [ "A", "B", "C", \%opt_for_C, "D", "E", \%opts_for_E, "F" ]

        In particular, for the class optlist the references should be hashrefs
        of class options (see "Class Options"), though key-value pair
        arrayrefs are also accepted.

    `role` *(OptList)*
        This is the list of roles to create, structured almost the same as the
        optlist for classes, but see "Role Options".

    `class_generator` *(OptList)*
        Kind of like `class`, but:

          [ "A", \&generator_for_A, "B", \&generator_for_B, ... ]

        "A" and "B" are not classes, but when `MyApp->generate_a(...)` is
        called, it will pass arguments to &generator_for_A which is expected
        to return a hashref like `\%opts_for_A`. Then a new pseudononymous
        class will be created with those options.

        See the FAQ for an example.

    `role_generator` *(OptList)*
        The same but for roles.

        See the FAQ for an example.

    `toolkit` *(Str)*
        The strings "Moo", "Moose", or "Mouse" are accepted and instruct
        MooX::Press to use your favourite OO toolkit. "Moo" is the default.

    `version` *(Num)*
        This has nothing to do with the version of MooX::Press you are using.
        It sets the `our $VERSION` variable for the classes and roles being
        generated.

    `authority` *(Str)*
        This sets the `our $AUTHORITY` variable for the classes and roles
        being generated.

        `version` and `authority` will be copied from the caller if they are
        not set, but you can set them to undef explicitly if you want to avoid
        that.

    `prefix` *(Str|Undef)*
        A namespace prefix for MooX::Press to put all your classes into. If
        MooX::Press is told to create a class "Animal" and `prefix` is set to
        "MyApp::OO", then it will create a class called "MyApp::OO::Animal".

        This is optional and defaults to the caller. If you wish to have no
        prefix, then pass an explicit `prefix => undef` option. (If the caller
        is `main`, then the prefix defaults to undef.)

        You can bypass the prefix for a specific class or a specific role
        using a leading double colon, like "::Animal" (or "main::Animal").

    `factory_package` *(Str|Undef)*
        A package name to install methods like the `new_cat` and `new_cow`
        methods in "SYNOPSIS".

        This defaults to prefix if the prefix is defined, and "Local"
        otherwise, but may be explicitly set to undef to suppress the creation
        of such methods. If the factory_package is "Local", you'll get a
        warning, except in `perl -e` one-liners.

        In every class (but not role) that MooX::Press builds, there will be a
        `FACTORY` method created so that, for example

          MyApp::Cow->FACTORY  # returns "MyApp"

        The factory package will also have a method called `qualify`
        installed, which uses the same logic as MooX::Press to add prefixes to
        class/role names.

          MyApp::Cow->FACTORY->qualify('Pig')     # 'MyApp::Pig'
          MyApp::Cow->FACTORY->qualify('::Pig')   # 'Pig'

        There will also be `get_role` and `get_class` methods:

          my $Clever = MyApp->get_role( 'Clever' );
          my $Brave  = MyApp->get_role( 'Brave' );
          my $Pig    = MyApp->get_class( 'Pig', $Clever, $Brave );
          my $wilbur = $Pig->new( name => 'Wilbur' );

        Class generators and role generators are also allowed; just follow the
        name with an arrayref of parameters.

        The factory package will have a global variable %PACKAGES where the
        keys are names of all the packages MooX::Press created for you, and
        the values are what kind of package they are:

          say $MyApp::PACKAGES{"MyApp::Cow"};     # 'class'

    `type_library` *(Str|Undef)*
        MooX::Press will automatically create a Type::Library-based type
        library with type constraints for all your classes and roles. It will
        be named using your prefix followed by "::Types".

        You can specify a new name or explicitly set to undef to suppress this
        behaviour, but a lot of the coercion features of MooX::Press rely on
        there being a type library.

        MooX::Press will create a get_type_for_package method that allows you
        to do this:

          MyApp::Types->get_type_for_package(class => "MyApp::Animal")

        MooX::Press will mark "MyApp/Types.pm" as loaded in %INC, so you can
        do things like:

          use MyApp::Types qw(Animal);

        And it won't complain about "MyApp/Types.pm" not being found.

        MooX::Press will install a `type_library` method into the factory
        package which returns the name of the type library, so you can do:

          MyApp->type_library->get_type_for_package(class => "MyApp::Animal")

    `caller` *(Str)*
        MooX::Press determines some things based on which package called it.
        If you are wrapping MooX::Press, you can fake the caller by passing it
        as an option.

    `end` *(CodeRef|ArrayRef[CodeRef])*
        After creating each class or role, this coderef will be called. It
        will be passed two parameters; the fully-qualified package name of the
        class or role, plus the string "class" or "role" as appropriate.

        Optional; defaults to nothing.

    `begin` *(CodeRef|ArrayRef[CodeRef])*
        Like `end`, but called before setting up any attributes, methods, or
        method modifiers. (But after loading Moo/Moose/Mouse.)

        Optional; defaults to nothing.

    `mutable` *(Bool)*
        Boolean to indicate that classes should be left mutable after creating
        them rather than making them immutable. Constructors for mutable
        classes are considerably slower than for immutable classes, so this is
        usually a bad idea.

        Only supported for Moose. Unnecessary for Moo anyway. Defaults to
        false.

    `factory_package_can` *(HashRef[CodeRef])*
        Hashref of additional subs to install into the factory package.

    `type_library_can` *(HashRef[CodeRef])*
        Hashref of additional subs to install into the type library package.

    `default_is`
        The default for the `is` option when defining attributes. The default
        `default_is` is "ro".

    At this top level, a shortcut is available for the 'class' and 'role'
    keys. Rather than:

      use MooX::Press (
        role => [
          'Quux',
          'Quuux' => { ... },
        ],
        class => [
          'Foo',
          'Bar' => { ... },
          'Baz' => { ... },
        ],
      );

    It is possible to write:

      use MooX::Press (
        'role:Quux'  => {},
        'role:Quuux' => { ... },
        'class:Foo'  => {},
        'class:Bar'  => { ... },
        'class:Baz'  => { ... },
      );

    This saves a level of indentation. (`=> undef` or `=> 1` are supported as
    synonyms for `=> {}`.)

    The `can`, `before`, `after`, `around`, `multimethod`, `symmethod`,
    `constant`, `with`, and `extends` options documented under Class Options
    can also be used as top-level import options to apply them to the factory
    package.

   Class Options
    Each class in the list of classes can be followed by a hashref of options:

      use MooX::Press (
        class => [
          'Foo' => \%options_for_foo,
          'Bar' => \%options_for_bar,
        ],
      );

    The following class options are supported.

    `extends` *(Str|ArrayRef[Str])*
        The parent class for this class.

        The prefix is automatically added. Include a leading "::" if you don't
        want the prefix to be added.

        Multiple inheritance is supported.

        If you are using Moose to extend a non-Moose class, MooseX::NonMoose
        will load automatically. (This also happens with MouseX::Foreign.)

    `with` *(ArrayRef[Str])*
        Roles for this class to consume.

        The prefix is automatically added. Include a leading "::" if you don't
        want the prefix to be added.

        Roles may include a trailing "?". When these are seen, the role will
        be created if it doesn't seem to exist. This is because sometimes it's
        useful to have roles to classify classes (and check them with the
        `does` method) even if those roles don't have any other functionality.

          use MooX::Press (
            prefix => 'Farm',
            class  => [
              'Sheep' => { with => ['Bleat?'] },
            ],
          );
  
          if (Farm::Sheep->new->does('Farm::Bleat')) {
            ...;
          }

        Without the "?", trying to compose a role that does not exist is an
        error.

    `has` *(OptList)*
        The list of attributes to add to the class as an optlist.

        The strings are the names of the attributes, but these strings may be
        "decorated" with sigils and suffixes:

        $foo
            Creates an attribute "foo" intended to hold a single value. This
            adds a type constraint forbidding arrayrefs and hashrefs but
            allowing any other value, including undef, strings, numbers, and
            any other reference.

        @foo
            Creates an attribute "foo" intended to hold a list of values. This
            adds a type constraint allowing arrayrefs or objects overloading
            `@{}`.

        %foo
            Creates an attribute "foo" intended to hold a collection of
            key-value pairs. This adds a type constraint allowing hashrefs or
            objects overloading `%{}`.

        `foo!`
            Creates an attribute "foo" which will be required by the
            constructor.

        An attribute can have both a sigil and a suffix.

        The references in the optlist may be attribute specification hashrefs,
        type constraint objects, or builder coderefs.

          # These mean the same thing...
          "name!" => Str,
          "name"  => { is => "ro", required => 1, isa => Str },

          # These mean the same thing...
          "age"   => sub { return 0 },
          "age"   => {
            is         => "ro",
            lazy       => 1,
            builder    => sub { return 0 },
            clearer    => "clear_age",
          },

        Type constraints can be any blessed object supported by the toolkit.
        For Moo, use Type::Tiny. For Moose, use Type::Tiny, MooseX::Types, or
        Specio. For Mouse, use Type::Tiny or MouseX::Types.

        Builder coderefs are automatically installed as methods like
        "YourPrefix::YourClass::_build_age()".

        For details of the hashrefs, see "Attribute Specifications".

    `can` *(HashRef[CodeRef|HashRef])*
        A hashref of coderefs to install into the package.

          package MyApp;
          use MooX::Press (
            class => [
              'Foo' => {
                 can => {
                   'bar' => sub { print "in bar" },
                 },
               },
            ],
          );
  
          package main;
          MyApp->new_foo()->bar();

        As an alternative, you can do this to prevent your import from getting
        cluttered with coderefs. Which you choose depends a lot on stylistic
        preference.

          package MyApp;
          use MooX::Press (
            class => ['Foo'],
          );
  
          package MyApp::Foo;
          sub bar { print "in bar" },
  
          package main;
          MyApp->new_foo()->bar();

    `multimethod` *(ArrayRef)*
        An arrayref of name-spec pairs suitable for passing to
        Sub::MultiMethod.

          package MyApp;
          use MooX::Press (
            class => [
              'Foo' => {
                 multimethod => [
                   'bar' => {
                     signature => [ 'HashRef' ],
                     code      => sub { my ($self, $hash)  = @_; ... },
                   },
                   'bar' => {
                     signature => [ 'ArrayRef' ],
                     code      => sub { my ($self, $array) = @_; ... },
                   },
                 ],
               },
            ],
          );

    `symmethod` *(ArrayRef)*
        An arrayref of name-spec pairs suitable for passing to Sub::SymMethod.

    `multifactory` *(ArrayRef)*
        Similar to `multimethod` but the methods are created in the factory
        package.

          package MyApp;
          use MooX::Press (
            class => [
              'Foo' => {
                 multifactory => [
                   'new_foo' => {
                     signature => [ 'HashRef' ],
                     code      => sub { my ($factory, $class, $hash)  = @_; ... },
                   },
                   'new_foo' => {
                     signature => [ 'ArrayRef' ],
                     code      => sub { my ($factory, $class, $array) = @_; ... },
                   },
                 ],
               },
            ],
          );
  
          my $obj1 = 'MyApp'->new_foo( {} );
          my $obj2 = 'MyApp'->new_foo( [] );

    `constant` *(HashRef[Item])*
        A hashref of scalar constants to define in the package.

          package MyApp;
          use MooX::Press (
            class => [
              'Foo' => {
                 constant => {
                   'BAR' => 42,
                 },
               },
            ],
          );
  
          package main;
          print MyApp::Foo::BAR, "\n";
          print MyApp->new_foo->BAR, "\n";

    `around` *(ArrayRef|HashRef)*
    `before` *(ArrayRef|HashRef)*
    `after` *(ArrayRef|HashRef)*
        Installs method modifiers.

          package MyApp;
          use MooX::Press (
            role => [
              'Loud' => {
                around => [
                  'greeting' => sub {
                    my $orig = shift;
                    my $self = shift;
                    return uc( $self->$orig(@_) );
                  },
                ],
              }
            ],
            class => [
              'Person' => {
                can => {
                  'greeting' => sub { "hello" },
                }
                subclass => [
                  'LoudPerson' => { with => 'Loud' },
                ],
              },
            ],
          );
  
          package main;
          print MyApp::LoudPerson->new->greeting, "\n";  # prints "HELLO"

    `coerce` *(ArrayRef)*
        When creating a class or role "Foo", MooX::Press will also create a
        Type::Tiny::Class or Type::Tiny::Role called "Foo". The `coerce`
        option allows you to add coercions to that type constraint. Coercions
        are called as methods on the class or role. This is perhaps best
        explained with an example:

          package MyApp;
          use Types::Standard qw(Str);
          use MooX::Press (
            class => [
              'Person' => {
                has    => [ 'name!' => Str ],
                can    => {
                  'from_name' => sub {
                    my ($class, $name) = @_;
                    return $class->new(name => $name);
                  },
                },
                coerce => [
                  Str, 'from_name',
                ],
              },
              'Company' => {
                has    => [ 'name!' => Str, 'owner!' => { isa => 'Person' } ],
              },
            ],
          );

        This looks simple but it's like the swan, graceful above the surface
        of the water, legs paddling frantically below.

        It creates a class called "MyApp::Person" with a "name" attribute, so
        you can do this kind of thing:

          my $bob = MyApp::Person->new(name => "Bob");
          my $bob = MyApp->new_person(name => "Bob");

        As you can see from the `can` option, it also creates a method
        "from_name" which can be used like this:

          my $bob = MyApp::Person->from_name("Bob");

        But here's where coercions come in. It also creates a type constraint
        called "Person" in "MyApp::Types" and adds a coercion from the `Str`
        type. The coercion will just call the "from_name" method.

        Then when the "MyApp::Company" class is created and the "owner"
        attribute is being set up, MooX::Press knows about the coercion from
        Str, and will set up coercion for that attribute.

          # So this should just work...
          my $acme = MyApp->new_company(name => "Acme Inc", owner => "Bob");
          print $acme->owner->name, "\n";

        Now that's out of the way, the exact structure for the arrayref of
        coercions can be explained. It is essentially a list of type-method
        pairs.

        The type may be either a blessed type constraint object (Type::Tiny,
        etc) or it may be a string type name for something that your type
        library knows about.

        The method is a string containing the method name to perform the
        coercion.

        This may optionally be followed by coderef to install as the method.
        The following two examples are equivalent:

          use MooX::Press (
            class => [
              'Person' => {
                has    => [ 'name!' => Str ],
                can    => {
                  'from_name' => sub {
                    my ($class, $name) = @_;
                    return $class->new(name => $name);
                  },
                },
                coerce => [
                  Str, 'from_name',
                ],
              },
            ],
          );

          use MooX::Press (
            class => [
              'Person' => {
                has    => [ 'name!' => Str ],
                coerce => [
                  Str, 'from_name' => sub {
                    my ($class, $name) = @_;
                    return $class->new(name => $name);
                  },
                ],
              },
            ],
          );

        In the second example, you can see the `can` option to install the
        "from_name" method has been dropped and the coderef put into `coerce`
        instead.

        In case it's not obvious, I suppose it's worth explicitly stating that
        it's possible to have coercions from many different types.

          use MooX::Press (
            class => [
              'Foo::Bar' => {
                coerce => [
                  Str,      'from_string', sub { ... },
                  ArrayRef, 'from_array',  sub { ... },
                  HashRef,  'from_hash',   sub { ... },
                  'FBaz',   'from_foobaz', sub { ... },
                ],
              },
              'Foo::Baz' => {
                type_name => 'FBaz',
               },
            ],
          );

        You should generally order the coercions from most specific to least
        specific. If you list "Num" before "Int", "Int" will never be used
        because all integers are numbers.

        There is no automatic inheritance for coercions because that does not
        make sense. If `Mammal->from_string($str)` is a coercion returning a
        "Mammal" object, and "Person" is a subclass of "Mammal", then there's
        no way for MooX::Press to ensure that when `Person->from_string($str)`
        is called, it will return a "Person" object and not some other kind of
        mammal. If you want "Person" to have a coercion, define the coercion
        in the "Person" class and don't rely on it being inherited from
        "Mammal".

        Coercions can also be specified using the attribute 'coerce' or
        'coercion' for methods/multimethods/factory methods, if they only take
        a single typed positional argument.

    `subclass` *(OptList)*
        Set up subclasses of this class. This accepts an optlist like the
        class list. It allows subclasses to be nested as deep as you like:

          package MyApp;
          use MooX::Press (
            class => [
              'Animal' => {
                 has      => ['name!'],
                 subclass => [
                   'Fish',
                   'Bird',
                   'Mammal' => {
                      can      => { 'lactate' => sub { ... } },
                      subclass => [
                        'Cat',
                        'Dog',
                        'Primate' => {
                          subclass => ['Monkey', 'Gorilla', 'Human'],
                        },
                      ],
                   },
                 ],
               },
            ];
          );
  
          package main;
          my $uncle = MyApp->new_human(name => "Bob");
          $uncle->isa('MyApp::Human');    # true
          $uncle->isa('MyApp::Primate');  # true
          $uncle->isa('MyApp::Mammal');   # true
          $uncle->isa('MyApp::Animal');   # true
          $uncle->isa('MyApp::Bird');     # false
          $uncle->can('lactate');         # eww, but true

        We just defined a nested heirarchy with ten classes there!

        Subclasses can be named with a leading "+" to tell them to use their
        parent class name as a prefix. So, in the example above, if you'd
        called your subclasses "+Mammal", "+Dog", etc, you'd end up with
        packages like "MyApp::Animal::Mammal::Dog". (In cases of multiple
        inheritance, it uses $ISA[0].)

    `factory` *(Str|ArrayRef|Undef)*
        This is the name for the method installed into the factory package. So
        for class "Cat", it might be "new_cat".

        The default is the class name (excluding the prefix), lowercased, with
        double colons replaced by single underscores, and with "new_" added in
        front. To suppress the creation of this method, set `factory` to an
        explicit undef.

        If set to an arrayref, it indicates you wish to create multiple
        methods in the factory package to make objects of this class.

          factory => [
            "grow_pig"                         => \"new_from_embryo",
            "new_pork", "new_bacon", "new_ham" => sub { ... },
            "new_pig", "new_swine",
          ],

        A scalarref indicates the name of a constructor and that the methods
        before are shortcuts for that constructor. So `MyApp->grow_pig(@args)`
        is a shortcut for `MyApp::Pig->new_from_embryo(@args)`.

        A coderef will have a custom method installed into the factory package
        so that `MyApp->new_pork(@args)` will act as a shortcut for:
        `$coderef->("MyApp", "MyApp::Pig", @args)`. Note that `new_bacon` and
        `new_ham` are just aliases for `new_bacon`.

        The `new_pig` and `new_swine` method names are followed by neither a
        coderef nor a scalarref, so are treated as if they had been followed
        by `\"new"`.

    `type_name` *(Str)*
        The name for the type being installed into the type library.

        The default is the class name (excluding the prefix), with double
        colons replaced by single underscores.

        This:

          use MooX::Press prefix => "ABC::XYZ", class => ["Foo::Bar"];

        Will create class "ABC::XYZ::Foo::Bar", a factory method
        `ABC::XYZ->new_foo_bar()`, and a type constraint "Foo_Bar" in type
        library "ABC::XYZ::Types".

    `toolkit` *(Str)*
        Override toolkit choice for this class and any child classes.

    `version` *(Num)*
        Override version number for this class and any child classes.

    `authority` *(Str)*
        Override authority for this class and any child classes.

        See "Import Options".

    `prefix` *(Str)*
        Override namespace prefix for this class and any child classes.

        See "Import Options".

    `factory_package` *(Str)*
        Override factory_package for this class and any child classes.

        See "Import Options".

    `mutable` *(Bool)*
        Override mutability for this class and any child classes.

        See "Import Options".

    `default_is` *(Str)*
        Override default_is for this class and any child classes.

        See "Import Options".

    `end` *(CodeRef|ArrayRef[CodeRef])*
        Override `end` for this class and any child classes.

        See "Import Options".

    `begin` *(CodeRef|ArrayRef[CodeRef])*
        Override `begin` for this class and any child classes.

          use MooX::Press::Keywords qw( true false );
          use MooX::Press (
            prefix => 'Library',
            class  => [
              'Book' => {
                begin => sub {
                  my $classname = shift;   # "Library::Book"
                  my $registry  = Type::Registry->for_class($classname);
                  $registry->alias_type('ArrayRef[Str]' => 'StrList')
                },
                has => {
                  'title'   => { type => 'Str',     required => true },
                  'authors' => { type => 'StrList', required => true },
                },
              },
            ],
          );

        See "Import Options".

    `import` *(OptList)*
        Allows you to import packages into classes.

          use MooX::Press (
            prefix => 'Library',
            class  => [
              toolkit  => 'Moose',
              import   => [ 'MooseX::StrictConstructor' ],
              ...,
            ],
          );

        Note that the coderefs you pass to MooX::Press are evaluated in the
        caller namespace, so this isn't very useful if you're looking to
        import functions. It can be useful for many MooX, MooseX, and MouseX
        extensions though.

    `overload` *(HashRef)*
        Options to pass to `use overload`.

    `abstract` *(Bool)*
        Marks the class as abstract. Abstract classes cannot have factories or
        coercions, and do not have a constuctor. They may be inherited from
        though. It is usually better to use roles.

   Role Options
    Options for roles are largely the same as for classes with the following
    exceptions:

    `requires` *(ArrayRef)*
        A list of methods required by the role.

          package MyApp;
          use MooX::Press (
            role => [
              'Milkable' => {
                requires => ['get_udder'],
                ...,
              },
            ],
          );

        Each method can optionally be followed by a method-defining hashref
        like in `can`:

          package MyApp;
          use MooX::Press (
            role => [
              'Milkable' => {
                requires => [
                  'get_udder', { signature => [...], named => 0 },
                ],
                ...,
              },
            ],
          );

        These hashrefs are currently ignored, but may be useful for people
        reading your role declarations.

    `extends` *(Any)*
        This option is disallowed.

    `can` *(HashRef[CodeRef|HashRef])*
        The alternative style for defining methods may cause problems with the
        order in which things happen. Because `use MooX::Press` happens at
        compile time, the following might not do what you expect:

          package MyApp;
          use MooX::Press (
            role   => ["MyRole"],
            class  => ["MyClass" => { with => "MyRole" }],
          );
  
          package MyApp::MyRole;
          sub my_function { ... }

        The "my_function" will not be copied into "MyApp::MyClass" because at
        the time the class is constructed, "my_function" doesn't yet exist
        within the role "MyApp::MyRole".

        You can combat this by changing the order you define things in:

          package MyApp::MyRole;
          sub my_function { ... }
  
          package MyApp;
          use MooX::Press (
            role   => ["MyRole"],
            class  => ["MyClass" => { with => "MyRole" }],
          );

        If you don't like having method definitions "above" MooX::Press in
        your file, then you can move them out into a module.

          # MyApp/Methods.pm
          #
          package MyApp::MyRole;
          sub my_function { ... }

          # MyApp.pm
          #
          package MyApp;
          use MyApp::Methods (); # load extra methods
          use MooX::Press (
            role   => ["MyRole"],
            class  => ["MyClass" => { with => "MyRole" }],
          );

        Or force MooX::Press to happen at runtime instead of compile time.

          package MyApp;
          require MooX::Press;
          import MooX::Press (
            role   => ["MyRole"],
            class  => ["MyClass" => { with => "MyRole" }],
          );
  
          package MyApp::MyRole;
          sub my_function { ... }

    `subclass` *(Any)*
        This option is not allowed.

    `factory` *(Any)*
        This option is not allowed.

    `mutable` *(Any)*
        This option is silently ignored.

    `overload` *(Any)*
        This option is not allowed.

    `abstract` *(Any)*
        This option is not allowed.

    `interface` *(Bool)*
        An interface is a "light" role.

        If a role is marked as an interface, it must not have any `can`,
        `before`, `after`, `around`, `has`, or `multimethod` options.
        `requires`, `constant`, and `type_name` are allowed. `with` is
        allowed; you should only use `with` to compose other interfaces (not
        full roles) though this is not currently enforced.

    `before_apply` *(CodeRef|ArrayRef[CodeRef])*
        Coderef to pass to `before_apply` from Role::Hooks.

    `after_apply` *(CodeRef|ArrayRef[CodeRef])*
        Coderef to pass to `after_apply` from Role::Hooks.

   Attribute Specifications
    Attribute specifications are mostly just passed to the OO toolkit
    unchanged, somewhat like:

      has $attribute_name => %attribute_spec;

    So whatever specifications (`required`, `trigger`, `coerce`, etc) the
    underlying toolkit supports should be supported.

    The following are exceptions:

    `is` *(Str)*
        This is optional rather than being required, and defaults to "ro" (or
        to `default_is` if you defined that).

        MooX::Press supports the Moo-specific values of "rwp" and "lazy", and
        will translate them if you're using Moose or Mouse.

        There is a special value `is => "private"` to create private
        attributes. These attributes cannot be set by the constructor (they
        always have `init_arg => undef`) and do not have accessor methods by
        default. They are stored inside-out, so cannot even be accessed using
        direct hashref access of the object. If you're thinking this makes
        them totally inaccessible, and therefore useless, think again.

        For private attributes, you can request an accessor as a coderef:

          my $my_attr;             # pre-declare lexical!
          use MooX::Press (
            'class:Foo' => {
              has => {
                'my_attr' => { is => 'private', accessor => \$my_attr },
              },
              can => {
                'my_method' => sub {
                  my $self = shift;
                  $self->$my_attr(42);        # writer
                  return $self->$my_attr();   # reader
                },
              },
            },
          );

        Private attributes may have defaults and builders (but they are always
        lazy!) They may also have `handles`. You may find you can do
        everything you need with the builders and delegations, so having an
        accessor is unnecessary.

        (As of version 0.050, setting `reader`, `writer`, `accessor`,
        `clearer`, or `predicate` to a scalarref will also work for *public*
        attributes too!)

    `isa` *(Str|Object)*
        When the type constraint is a string, it is always assumed to be a
        class name and your application's namespace prefix is added. So `isa
        => "HashRef"` doesn't mean what you think it means. It means an object
        blessed into the "YourApp::HashRef" class.

        That is a feature though, not a weakness.

          use MooX::Press (
            prefix  => 'Nature',
            class   => [
              'Leaf'  => {},
              'Tree'  => {
                has  => {
                  'nicest_leaf'  => { isa => 'Leaf' },
                },
              },
            ],
          );

        The `Nature::Tree` and `Nature::Leaf` classes will be built, and
        MooX::Press knows that the `nicest_leaf` is supposed to be a blessed
        `Nature::Leaf` object.

        String type names can be prefixed with `@` or `%` to indicate an
        arrayref or hashref of a type:

          use MooX::Press (
            prefix  => 'Nature',
            class   => [
              'Leaf'  => {},
              'Tree'  => {
                has  => {
                  'foliage'  => { isa => '@Leaf' },
                },
              },
            ],
          );

        For more everything else, use blessed type constraint objects, such as
        those from Types::Standard, or use `type` as documented below.

          use Types::Standard qw( Str );
          use MooX::Press (
            prefix  => 'Nature',
            class   => [
              'Leaf'  => {},
              'Tree'  => {
                has  => {
                  'foliage'  => { isa => '@Leaf' },
                  'species'  => { isa => Str },
                },
              },
            ],
          );

    `type` *(Str)*
        `type => "HashRef"` does what you think `isa => "HashRef"` should do.
        More specifically it searches (by name) your type library, along with
        Types::Standard, Types::Common::Numeric, and Types::Common::String to
        find the type constraint it thinks you wanted. It's smart enough to
        deal with parameterized types, unions, intersections, and complements.

          use MooX::Press (
            prefix  => 'Nature',
            class   => [
              'Leaf'  => {},
              'Tree'  => {
                has  => {
                  'foliage'  => { isa  => '@Leaf' },
                  'species'  => { type => 'Str' },
                },
              },
            ],
          );

        `type => $blessed_type_object` does still work.

        `type` and `isa` are basically the same as each other, but differ in
        how they'll interpret a string. `isa` assumes it's a class name as
        applies the package prefix to it; `type` assumes it's the name of a
        type constraint which has been defined in some type library somewhere.

    `does` *(Str)*
        Similarly to `isa`, these will be given your namespace prefix.

          # These mean the same...
          does => 'SomeRole',
          type => Types::Standard::ConsumerOf['MyApp::SomeRole'],

    `enum` *(ArrayRef[Str])*
        This is a cute shortcut for an enum type constraint.

          # These mean the same...
          enum => ['foo', 'bar'],
          type => Types::Standard::Enum['foo', 'bar'],

        If the type constraint is set to an enum and `handles` is provided,
        then MooX::Press will automatically load MooX::Enumeration or
        MooseX::Enumeration as appropriate. (This is not supported for Mouse.)

          use MooX::Press (
            prefix  => 'Nature',
            class   => [
              'Leaf'  => {
                has  => {
                  'colour' => {
                    enum    => ['green', 'red', 'brown'],
                    handles => 2,
                    default => 'green',
                  },
                },
               },
            ],
          );
  
          my $leaf = Nature->new_leaf;
          if ( $leaf->colour_is_green ) {
            print "leaf is green!\n";
          }

    `handles_via` *(Str|ArrayRef[Str])*
        If your attribute has a `handles_via` option, MooX::Press will load
        Sub::HandlesVia for you.

    `handles` *(ArrayRef|HashRef|RoleName)*
        `handles` is effectively a mapping of methods in the package being
        defined to methods in a target package. If `handles` is a hashref,
        then it is obvious how that works. If `handles` is a role name, then
        the mapping includes all the methods that are part of the role's API,
        and they map to methods of the same name in the target package. (Only
        Moose and Mouse support `handles` being a role name.)

        For attributes with an enum type constraint, the special values
        `handles => 1` and `handles => 2` described above also work.

        When `handles` is an arrayref, then the different backend modules
        would interpret it differently:

          # Moo, Moose, Mouse, Sub::HandlesVia, Moo(se)X::Enumeration
          [ "value1", "value2", "value3", "value4" ]
  
          # Lexical::Accessor
          [ "key1" => "value1", "key2" => "value2" ]

        Since version 0.050, MooX::Press smooths over the differences between
        them by converting these arrayrefs to hashrefs. Rather surprisingly,
        *the Lexical::Accessor interpretation of arrayrefs is used*. It is
        treated as a list of key-value pairs.

        This is because even though that's the minority interpretation, it's
        the more useful interpretation, allowing methods from the target
        package to be given a different name in the package being defined, or
        even assigned to lexical variables.

          has => [
            'ua' => {
              is      => 'bare',
              default => sub { HTTP::Tiny->new },
              handles => [
                \$get  => 'get',
                \$post => 'post',
              ],
            },
          ],

        Now $get will be a coderef that you can call as a method:

          $self->$get($url);   # same as $self->{ua}->get($url)

        If you use `handles => \%hash`, you should get expected behaviour. If
        you use `handles => \@array`, just be aware that your array is going
        to be interpreted like a hash from MooX::Press 0.050 onwards!

    `coerce` *(Bool|CodeRef)*
        MooX::Press automatically implies `coerce => 1` when you give a type
        constraint that has a coercion. If you don't want coercion then
        explicitly provide `coerce => 0`.

        `coerce => sub { ... }` is supported even for Moose and Mouse.

    `builder` *("1"|Str|CodeRef)*
        MooX::Press supports the Moo-specific `builder => 1` and `builder =>
        sub { ... }` and will translate them if you're using Moose or Mouse.

    `trigger` *("1"|Str|CodeRef)*
        MooX::Press supports the Moo-specific `trigger => 1` and `trigger =>
        $methodname` and will translate them if you're using Moose or Mouse.

    `clearer` *("1"|Str)*
        MooX::Press supports the Moo-specific `clearer => 1` and will
        translate it if you're using Moose or Mouse.

    `default` *(CodeRef|~Ref|Overloaded|ScalarRef)*
        Coderefs and non-reference values can be used as defaults the same as
        in Moo/Moose/Mouse.

        Blessed Ask::Question objects are additionally supported as defaults.
        The `type` of the attribute will automatically be injected as the
        target type of the question if the target type is missing.

        A scalarref is converted to an Ask::Question object so:

          has age => ( is => 'ro', type => 'Int', default => \"Enter age" );

        Will require age to be an integer, and if it's not provided to the
        constructor, Ask will prompt the user via STDIN/STDOUT, a GUI dialogue
        box, or whatever other method is available.

   Method Signatures
    Most places where a coderef is expected, MooX::Press will also accept a
    hashref of the form:

      {
        signature  => [ ... ],
        named      => 1,
        code       => sub { ... },
        attributes => [ ... ],
      }

    The `signature` is a specification to be passed to `compile` or
    `compile_named_oo` from Type::Params (depending on whether `named` is true
    or false).

    Unlike Type::Params, these signatures allow type constraints to be given
    as strings, which will be looked up by name.

    This should work for `can`, `factory_can`, `type_library_can`, `factory`,
    `builder` methods, and method modifiers. (Though if you are doing type
    checks in both the methods and method modifiers, this may result in
    unnecessary duplication of checks.)

    The invocant ($self) is not included in the signature. (For `around`
    method modifiers, the original coderef $orig is logically a second
    invocant. For `factory` methods installed in the factory package, the
    factory package name and class name are both considered invocants.)

    Example with named parameters:

      use MooX::Press (
        prefix => 'Wedding',
        class  => [
          'Person' => { has => [qw( $name $spouse )] },
          'Officiant' => {
            can => {
              'marry' => {
                signature => [ bride => 'Person', groom => 'Person' ],
                named     => 1,
                code      => sub {
                  my ($self, $args) = @_;
                  $args->bride->spouse($args->groom);
                  $args->groom->spouse($args->bride);
                  printf("%s, you may kiss the bride\n", $args->groom->name);
                  return $self;
                },
              },
            },
          },
        ],
      );
  
      my $alice  = Wedding->new_person(name => 'Alice');
      my $bob    = Wedding->new_person(name => 'Robert');
  
      my $carol  = Wedding->new_officiant(name => 'Carol');
      $carol->marry(bride => $alice, groom => $bob);

    Example with positional parameters:

      use MooX::Press (
        prefix => 'Wedding',
        class  => [
          'Person' => { has => [qw( $name $spouse )] },
          'Officiant' => {
            can => {
              'marry' => {
                signature => [ 'Person', 'Person' ],
                code      => sub {
                  my ($self, $bride, $groom) = @_;
                  $bride->spouse($groom);
                  $groom->spouse($bride);
                  printf("%s, you may kiss the bride\n", $groom->name);
                  return $self;
                },
              },
            },
          },
        ],
      );
  
      my $alice  = Wedding->new_person(name => 'Alice');
      my $bob    = Wedding->new_person(name => 'Robert');
  
      my $carol  = Wedding->new_officiant(name => 'Carol');
      $carol->marry($alice, $bob);

    Methods with a mixture of named and positional parameters are not
    supported. If you really want such a method, don't provide a signature;
    just provide a coderef and manually unpack @_.

    Advanced features:

    `signature` may be a coderef, which is passed @_ (minus invocants) and is
    expected to return a new @_ in list context after checking and optionally
    coercing parameters.

    Setting `optimize => 1` tells MooX::Press to attempt to perform additional
    compile-time optimizations on the signature to make it slightly faster at
    runtime. (Sometimes it will find it's unable to optimize anything, so
    you've just wasted time at compile time.)

    `code` can be a string of Perl code like `sub { ... }` instead of a real
    coderef. This doesn't let you close over any variables, but if you can
    provide code this way, it might be slightly faster.

  Optimization Features
    MooX::Press will automatically load and apply MooX::XSConstructor if it's
    installed, which will optmimize constructors for some very basic classes.
    Again, this is only for Moo classes.

    MooX::Press will automatically load MooseX::XSAccessor if it's installed,
    which speeds up some Moose accessors. This is only used for Moose classes.

  Subclassing MooX::Press
    All the internals of MooX::Press are called as methods, which should make
    subclassing it possible.

      package MyX::Press;
      use parent 'MooX::Press';
      use Class::Method::Modifiers;
  
      around make_class => sub {
        my $orig = shift;
        my $self = shift;
        my ($name, %opts) = @_;
        ## Alter %opts here
        my $qname = $self->$orig($name, %opts);
        ## Maybe do something to the returned class
        return $qname;
      };

    It is beyond the scope of this documentation to fully describe all the
    methods you could potentially override, but here is a quick summary of
    some that may be useful.

    `import(%opts|\%opts)`
    `qualify_name($name, $prefix)`
    `croak($error)`
    `prepare_type_library($qualified_name)`
    `make_type_for_role($name, %opts)`
    `make_type_for_class($name, %opts)`
    `make_role($name, %opts)`
    `make_class($name, %opts)`
    `install_methods($qualified_name, \%methods)`
    `install_constants($qualified_name, \%values)`

FAQ
    This is a new module so I haven't had any questions about it yet, let
    alone any frequently asked ones, but I will anticipate some.

  Why doesn't MooX::Press automatically import strict and warnings for me?
    Your MooX::Press import will typically contain a lot of strings, maybe
    some as barewords, some coderefs, etc. You should manually import strict
    and warnings before importing MooX::Press to ensure all of that is covered
    by strictures.

  Why all the factory stuff?
    Factories are big and cool and they put lots of smoke into our atmosphere.

    Also, if you do something like:

      use constant APP => 'MyGarden';
      use MooX::Press (
        prefix => APP,
        role  => [
          'LeafGrower' => {
            has => [ '@leafs' => sub { [] } ],
            can => {
              'grow_leaf' => sub {
                my $self = shift;
                my $leaf = $self->FACTORY->new_leaf;
                push @{ $self->leafs }, $leaf;
                return $leaf;
              },
            },
          },
        ],
        class => [
          'Leaf',
          'Tree'  => { with => ['LeafGrower'] },
        ],
      );
  
      my $tree = APP->new_tree;
      my $leaf = $tree->grow_leaf;

    And you will notice that the string "MyGarden" doesn't appear anywhere in
    the definitions for any of the classes and roles. The prefix could be
    changed to something else entirely and all the classes and roles, all the
    methods within them, would continue to work.

    Whole collections of classes and roles now have portable namespaces. The
    same classes and roles could be used with different prefixes in different
    scripts. You could load two different versions of your API in the same
    script with different prefixes. The possibilities are interesting.

    Factory methods are also exportable.

      use MyGarden 'new_tree';
  
      my $maple = new_tree();  # called as a function, not a method

    Exported functions can be renamed (see Exporter::Tiny).

      use MyGarden 'new_tree' => { -as => 'germinate' };
  
      my $maple = germinate();

  Why doesn't `$object->isa("Leaf")` work?
    In the previous question, `$object->isa("Leaf")` won't work to check if an
    object is a Leaf. This is because the full name of the class is
    "MyGarden::Leaf".

    You can of course check `$object->isa("MyGarden::Leaf")` but this means
    you're starting to hard-code class names and prefixes again, which is one
    of the things MooX::Press aims to reduce.

    The "correct" way to check something is a leaf is:

      use MyGarden::Types qw( is_Leaf );
  
      if ( is_Leaf($object) ) {
        ...;
      }

    Or if you really want to use `isa`:

      use MyGarden::Types qw( Leaf );
  
      if ( $object->isa(Leaf->class) ) {
        ...;
      }

    However, the type library is only available *after* you've used
    MooX::Press. This can make it tricky to refer to types within your
    methods.

      use constant APP => 'MyGarden';
      use MooX::Press (
        prefix => APP,
        class => [
          'Leaf',
          'Tree'  => {
            can => {
              'add_leaf' => sub {
                my ($self, $leaf) = @_;
            
                # How to check is_Leaf() here?
                # It's kind of tricky!
            
                my $t = $self->FACTORY->type_library->get_type('Leaf');
                if ($t->check($leaf)) {
                  ...;
                }
              },
            },
          },
        ],
      );

    As of version 0.019, MooX::Press has method signatures, so you're less
    likely to need to check types within your methods; you can just do it in
    the signature. This won't cover every case you need to check types, but it
    will cover the common ones.

      use constant APP => 'MyGarden';
      use MooX::Press (
        prefix => APP,
        class => [
          'Leaf',
          'Tree'  => {
            can => {
              'add_leaf' => {
                signature => ['Leaf'],
                code      => sub {
                  my ($self, $leaf) = @_;
                  ...;
                },
              },
            },
          },
        ],
      );

    This also makes your code more declarative and less imperative, and that
    is a Good Thing, design-wise.

  The plural of "leaf" is "leaves", right?
    Yeah, but that sounds like something is leaving.

  How do generators work?
    A class generator is like a class of classes.

    A role generator is like a class of roles.

      use MooX::Press (
        prefix => 'MyApp',
        class  => [
          'Animal' => {
            has => ['$name'],
          },
        ],
        class_generator => [
          'Species' => sub {
            my ($gen, $binomial) = @_;
            return {
              extends  => ['Animal'],
              constant => { binomial => $binomial },
            };
          },
        ],
      );

    This generates MyApp::Animal as a class, as you might expect, but also
    creates a class generator called MyApp::Species.

    MyApp::Species is not itself a class but it can make classes. Calling
    either `MyApp::Species->generate_package` or `MyApp->generate_species`
    will compile a new class and return the class name as a string.

      my $Human = MyApp->generate_species('Homo sapiens');
      my $Dog   = MyApp->generate_species('Canis familiaris');
  
      my $alice = $Human->new(name => 'Alice');
      say $alice->name;      # Alice
      say $alice->binomial;  # Homo sapiens
  
      my $fido  = $Dog->new(name => 'Fido');
      $fido->isa($Dog);               # true
      $fido->isa($Human);             # false
      $fido->isa('MyApp::Animal');    # true
      $fido->isa('MyApp::Species');   # false!!!
  
      use Types::Standard -types;
      use MyApp::Types -types;
  
      is_ClassName($fido)             # false
      is_Object($fido)                # true
      is_Animal($fido);               # true
      is_SpeciesInstance($fido);      # true
      is_SpeciesClass($fido);         # false
      is_ClassName($Dog)              # true
      is_Object($Dog)                 # false
      is_Animal($Dog);                # false
      is_SpeciesInstance($Dog);       # false
      is_SpeciesClass($Dog);          # true

    Note that there is no Species type created, but instead a pair of types is
    created: SpeciesClass and SpeciesInstance.

    It is also possible to inherit from generated classes.

      use MooX::Press (
        prefix => 'MyApp',
        class  => [
          'Animal' => {
            has => ['$name'],
          },
          'Dog' => {
            extends => [ 'Species' => ['Canis familiaris'] ]
          },
        ],
        class_generator => [
          'Species' => sub {
            my ($gen, $binomial) = @_;
            return {
              extends  => ['Animal'],
              constant => { binomial => $binomial },
            };
          },
        ],
      );
  
      my $fido = MyApp->new_dog(name => 'Fido');

    The inheritance heirarchy for $fido is something like:

      Moo::Object
      ->  MyApp::Animal
        ->  MyApp::Species::__GEN000001__
          ->  MyApp::Dog

    Note that MyApp::Species itself isn't in that heirarchy!

    Generated roles work pretty much the same, but `role_generator` instead of
    `class_generator`, `does` instead of `isa`, and `with` instead of
    `extends`.

    No type constraints are automatically created for generated roles.

  Are you insane?
    Quite possibly.

BUGS
    Please report any bugs to
    <http://rt.cpan.org/Dist/Display.html?Queue=MooX-Press>.

SEE ALSO
    Zydeco::Lite, Zydeco.

    Moo, MooX::Struct, Types::Standard.

    portable::loader.

AUTHOR
    Toby Inkster <tobyink@cpan.org>.

COPYRIGHT AND LICENCE
    This software is copyright (c) 2019-2020 by Toby Inkster.

    This is free software; you can redistribute it and/or modify it under the
    same terms as the Perl 5 programming language system itself.

DISCLAIMER OF WARRANTIES
    THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
    WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
    MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.