NAME
    Perinci::Sub::Wrapper - A multi-purpose subroutine wrapping framework

VERSION
    version 0.20

SYNOPSIS
     use Perinci::Sub::Wrapper qw(wrap_sub);
     my $res = wrap_sub(sub => sub {die "test\n"}, meta=>{...});
     my ($wrapped, $meta) = ($res->[2]{sub}, $res->[2]{meta});
     $wrapped->(); # call the wrapped function

DESCRIPTION
    Perinci::Sub::Wrapper is an extensible subroutine wrapping framework. It
    works by creating a single "large" wrapper function from a composite
    bits of code, instead of using multiple small wrappers (a la Python's
    decorator). The single-wrapper approach has the benefit of smaller
    function call overhead. You can still wrap multiple times if needed.

    This module is used to enforce Rinci properties, e.g. "args" (by
    performing schema validation before calling the function), "timeout" (by
    doing function call inside an "eval()" and using "alarm()" to limit the
    execution), or "retry" (by wrapping function call inside a simple retry
    loop).

    It can also be used to convert argument passing style, e.g. from
    "args_as" "array" to "args_as" "hash", so you can call function using
    named arguments even though the function accepts positional arguments.

    There are many other possible uses.

    This module uses Log::Any for logging.

EXTENDING
    The framework is simple and extensible. Please delve directly into the
    source code for now. Some notes:

    The internal uses OO.

    The main wrapper building mechanism is in the "wrap()" method.

    For each Rinci property, it will call "handle_NAME()" wrapper handler
    method. The "handlemeta_NAME()" methods are called first, to determine
    order of processing. You can supply these methods either by subclassing
    the class or, more simply, monkeypatching the method in the
    "Perinci::Sub::Wrapper" package.

    The wrapper handler method will be called with a hash argument,
    containing these keys: value (property value), new (this key will exist
    if "convert" argument of "wrap()" exists, to convert a property to a new
    value).

    For properties that have name in the form of "NAME1.NAME2.NAME3" (i.e.,
    dotted) only the first part of the name will be used (i.e.,
    "handle_NAME1()").

METHODS
    The OO interface is only used internally or when you want to extend the
    wrapper.

SEE ALSO
    Perinci

FUNCTIONS
  wrap_sub(%args) -> [status, msg, result, meta]
    Wrap subroutine to do various things, like enforcing Rinci properties.

    Will wrap subroutine and bless the generated wrapped subroutine (by
    default into 'Perinci::Sub::Wrapped') as a way of marking that the
    subroutine is a wrapped one.

    Arguments ('*' denotes required arguments):

    *   compile => *bool* (default: 1)

        Whether to compile the generated wrapper.

        Can be set to 0 to not actually wrap but just return the generated
        wrapper source code.

    *   convert* => *hash*

        Properties to convert to new value.

        Not all properties can be converted, but these are a partial list of
        those that can: v (usually do not need to be specified when
        converting from 1.0 to 1.1, will be done automatically), argsas,
        resultnaked, default_lang.

    *   meta* => *hash*

        The function metadata.

    *   normalize_schema => *bool* (default: 1)

        Whether to normalize schemas in metadata.

        By default, wrapper normalize Sah schemas in metadata, like in
        'args' or 'result' property, for convenience so that it does not
        need to be normalized again prior to use. If you want to turn off
        this behaviour, set to false.

    *   remove_internal_properties => *bool* (default: 1)

        Whether to remove properties prefixed with _.

        By default, wrapper removes internal properties (properties which
        start with underscore) in the new metadata. Set this to false to
        keep them.

    *   sub* => *code*

        The code to wrap.

    *   trap => *bool* (default: 1)

        Whether to trap exception using an eval block.

        If set to true, will wrap call using an eval {} block and return 500
        /undef if function dies. Note that if some other properties requires
        an eval block (like 'timeout') an eval block will be added
        regardless of this parameter.

    Return value:

    Returns an enveloped result (an array). First element (status) is an
    integer containing HTTP status code (200 means OK, 4xx caller error, 5xx
    function error). Second element (msg) is a string containing error
    message, or 'OK' if status is 200. Third element (result) is optional,
    the actual result. Fourth element (meta) is called result metadata and
    is optional, a hash that contains extra information.

AUTHOR
    Steven Haryanto <stevenharyanto@gmail.com>

COPYRIGHT AND LICENSE
    This software is copyright (c) 2012 by Steven Haryanto.

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

