=pod

=head1 NAME

autobox - call methods on native types

=head1 SYNOPSIS

    use autobox;

    # integers

        my $range = 10->to(1); # [ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]

    # floats

        my $error = 3.1415927->minus(22/7)->abs();

    # strings

        my @list = 'SELECT * FROM foo'->list();
        my $greeting = "Hello, world!"->upper(); # "HELLO, WORLD!"

        $greeting->for_each(\&character_handler);

    # arrays and array refs

        my $schwartzian = @_->map(...)->sort(...)->map(...);
        my $hash = [ 'SELECT * FROM foo WHERE id IN (?, ?)', 1, 2 ]->hash();

    # hashes and hash refs

        { alpha => 'beta', gamma => 'vlissides' }->for_each(...);
        %hash->keys();

    # code refs

        my $plus_five = (\&add)->curry()->(5);
        my $minus_three = sub { $_[0] - $_[1] }->reverse->curry->(3);

    # can, isa, VERSION, import and unimport can be accessed via autobox_class

        42->autobox_class->isa('MyNumber');
        say []->autobox_class->VERSION;

=head1 DESCRIPTION

The autobox pragma allows methods to be called on integers, floats, strings, arrays,
hashes, and code references in exactly the same manner as blessed references.

Autoboxing is transparent: values are not blessed into their (user-defined)
implementation class (unless the method elects to bestow such a blessing) - they simply
use its methods as though they are.

The classes (packages) into which the native types are boxed are fully configurable.
By default, a method invoked on a non-object value is assumed to be
defined in a class whose name corresponds to the C<ref()> type of that
value - or SCALAR if the value is a non-reference.

This mapping can be overridden by passing key/value pairs to the C<use autobox>
statement, in which the keys represent native types, and the values
their associated classes.

As with regular objects, autoboxed values are passed as the first argument of the specified method.
Consequently, given a vanilla C<use autobox>:

    "Hello, world!"->upper()

is invoked as:

    SCALAR::upper("hello, world!")

while:

    [ 1 .. 10 ]->for_each(sub { ... })

resolves to:

    ARRAY::for_each([ 1 .. 10 ], sub { ... })

Values beginning with the array C<@> and hash C<%> sigils are passed by
reference, i.e. under the default bindings:

    @array->join(', ')
    @{ ... }->length()
    %hash->keys()
    %$hash->values()

are equivalent to:

    ARRAY::join(\@array, ', ')
    ARRAY::length(\@{ ... })
    HASH::keys(\%hash)
    HASH::values(\%$hash)

Multiple C<use autobox> statements can appear in the same scope. These are merged both "horizontally" (i.e.
multiple classes can be associated with a particular type) and "vertically" (i.e. multiple classes can be associated
with multiple types).

Thus:

    use autobox SCALAR => 'Foo';
    use autobox SCALAR => 'Bar';

- associates SCALAR types with a synthetic class whose C<@ISA> includes both Foo and Bar (in that order).

Likewise:

    use autobox SCALAR => 'Foo';
    use autobox SCALAR => 'Bar';
    use autobox ARRAY  => 'Baz';

and

    use autobox SCALAR => [ 'Foo', 'Bar' ];
    use autobox ARRAY  => 'Baz';

- bind SCALAR types to the Foo and Bar classes and ARRAY types to Baz.

autobox is lexically scoped, and bindings for an outer scope
can be extended or countermanded in a nested scope:

    {
        use autobox; # default bindings: autobox all native types
        ...

        {
            # appends 'MyScalar' to the @ISA associated with SCALAR types
            use autobox SCALAR => 'MyScalar';
            ...
        }

        # back to the default (no MyScalar)
        ...
    }

Autoboxing can be turned off entirely by using the C<no> syntax:

    {
        use autobox;
        ...
        no autobox;
        ...
    }

- or can be selectively disabled by passing arguments to the C<no autobox> statement:

    use autobox; # default bindings

    no autobox qw(SCALAR);

    []->foo(); # OK: ARRAY::foo([])

    "Hello, world!"->bar(); # runtime error

Autoboxing is not performed for barewords, i.e.

    my $foo = Foo->new();

and:

    my $foo = new Foo;

behave as expected.

Methods are called on native types by means of the L<arrow operator|perlop/"The Arrow Operator">. As with
regular objects, the right hand side of the operator can either be a bare method name or a variable containing
a method name or subroutine reference. Thus the following are all valid:

    sub method1 { ... }
    my $method2 = 'some_method';
    my $method3 = sub { ... };
    my $method4 = \&some_method;

    " ... "->method1();
    [ ... ]->$method2();
    { ... }->$method3();
    sub { ... }->$method4();

A native type is only associated with a class if the type => class mapping
is supplied in the C<use autobox> statement. Thus the following will not work:

    use autobox SCALAR => 'MyScalar';

    @array->some_array_method();

- as no class is specified for the ARRAY type. Note: the result of calling a method
on a native type that is not associated with a class is the usual runtime error message:

    Can't call method "some_array_method" on unblessed reference at ...

As a convenience, there is one exception to this rule. If C<use autobox> is invoked with no arguments
(ignoring the DEBUG option) the four main native types are associated with classes of the same name.

Thus:

    use autobox;

- is equivalent to:

    use autobox {
        SCALAR => 'SCALAR',
        ARRAY  => 'ARRAY',
        HASH   => 'HASH',
        CODE   => 'CODE',
    }

This facilitates one-liners and prototypes:

    use autobox;

    sub SCALAR::split { [ split '', $_[0] ] }
    sub ARRAY::length { scalar @{$_[0]} }

    print "Hello, world!"->split->length();

However, using these default bindings is not recommended as there's no guarantee that another
piece of code won't trample over the same namespace/methods.

=head1 OPTIONS

A mapping from native types to their user-defined classes can be specified
by passing a hashref or a list of key/value pairs to the C<use autobox> statement.

The following example shows the range of valid arguments:

    use autobox {
        SCALAR    => 'MyScalar'                     # class name
        ARRAY     => 'MyNamespace::',               # class prefix (ending in '::')
        HASH      => [ 'MyHash', 'MyNamespace::' ], # one or more class names and/or prefixes
        CODE      => ...,                           # any of the 3 value types above
        INTEGER   => ...,                           # any of the 3 value types above
        FLOAT     => ...,                           # any of the 3 value types above
        NUMBER    => ...,                           # any of the 3 value types above
        STRING    => ...,                           # any of the 3 value types above
        UNDEF     => ...,                           # any of the 3 value types above
        UNIVERSAL => ...,                           # any of the 3 value types above
        DEFAULT   => ...,                           # any of the 3 value types above
        DEBUG     => ...                            # boolean or coderef
    }

The INTEGER, FLOAT, NUMBER, STRING, SCALAR, ARRAY, HASH, CODE, UNDEF, DEFAULT and UNIVERSAL options can take
three different types of value:

=over

=item *

A class name, e.g.

    use autobox INTEGER => 'MyInt';

This binds the specified native type to the specified class. All methods invoked on
values of type C<key> will be dispatched as methods of the class specified in
the corresponding C<value>.

=item *

A namespace: this is a class prefix (up to and including the final '::')
to which the specified type name (INTEGER, FLOAT, STRING etc.) will be appended:

Thus:

    use autobox ARRAY => 'Prelude::';

is equivalent to:

    use autobox ARRAY => 'Prelude::ARRAY';

=item *

A reference to an array of class names and/or namespaces. This associates multiple classes with the
specified type.

=back

=head2 DEFAULT

The C<DEFAULT> option specifies bindings for any of the four default types (SCALAR, ARRAY, HASH and CODE)
not supplied in the C<use autobox> statement. As with the other options, the C<value> corresponding to
the C<DEFAULT> C<key> can be a class name, a namespace, or a reference to an array containing one or
more class names and/or namespaces.

Thus:

    use autobox {
        STRING  => 'MyString',
        DEFAULT => 'MyDefault',
    }

is equivalent to:

    use autobox {
        STRING  => 'MyString',
        SCALAR  => 'MyDefault',
        ARRAY   => 'MyDefault',
        HASH    => 'MyDefault',
        CODE    => 'MyDefault',
    }

Which in turn is equivalent to:

    use autobox {
        INTEGER => 'MyDefault',
        FLOAT   => 'MyDefault',
        STRING  => [ 'MyString', 'MyDefault' ],
        ARRAY   => 'MyDefault',
        HASH    => 'MyDefault',
        CODE    => 'MyDefault',
    }

Namespaces in DEFAULT values have the default type name appended, which, in the case of defaulted SCALAR types,
is SCALAR rather than INTEGER, FLOAT etc.

Thus:

    use autobox {
        ARRAY   => 'MyArray',
        HASH    => 'MyHash',
        CODE    => 'MyCode',
        DEFAULT => 'MyNamespace::',
    }

is equivalent to:

    use autobox {
        INTEGER => 'MyNamespace::SCALAR',
        FLOAT   => 'MyNamespace::SCALAR',
        STRING  => 'MyNamespace::SCALAR',
        ARRAY   => 'MyArray',
        HASH    => 'MyHash',
        CODE    => 'MyCode',
    }

Any of the four default types can be exempted from defaulting to the DEFAULT value by supplying a value of undef:

    use autobox {
        HASH    => undef,
        DEFAULT => 'MyDefault',
    }

    42->foo # ok: MyDefault::foo
    []->bar # ok: MyDefault::bar

    %INC->baz # not ok: runtime error

=head2 UNDEF

The pseudotype, UNDEF, can be used to autobox undefined values. These are not autoboxed by default.

This doesn't work:

    use autobox;

    undef->foo(); # runtime error

This works:

    use autobox UNDEF => 'MyUndef';

    undef->foo(); # ok

So does this:

    use autobox UNDEF => 'MyNamespace::';

    undef->foo(); # ok

=head2 NUMBER, SCALAR and UNIVERSAL

The virtual types NUMBER, SCALAR and UNIVERSAL function as macros or shortcuts which create
bindings for their subtypes. The type hierarchy is as follows:

  UNIVERSAL -+
             |
             +- SCALAR -+
             |          |
             |          +- NUMBER -+
             |          |          |
             |          |          +- INTEGER
             |          |          |
             |          |          +- FLOAT
             |          |
             |          +- STRING
             |
             +- ARRAY
             |
             +- HASH
             |
             +- CODE

Thus:

    use autobox NUMBER => 'MyNumber';

is equivalent to:

    use autobox {
        INTEGER => 'MyNumber',
        FLOAT   => 'MyNumber',
    }

And:

    use autobox SCALAR => 'MyScalar';

is equivalent to:

    use autobox {
        INTEGER => 'MyScalar',
        FLOAT   => 'MyScalar',
        STRING  => 'MyScalar',
    }

Virtual types can also be passed to C<unimport> via the C<no autobox> syntax. This disables autoboxing
for the corresponding subtypes, e.g.

    no autobox qw(NUMBER);

is equivalent to:

    no autobox qw(INTEGER FLOAT);

Virtual type bindings can be mixed with ordinary bindings to provide fine-grained control over
inheritance and delegation. For instance:

    use autobox {
        INTEGER => 'MyInteger',
        NUMBER  => 'MyNumber',
        SCALAR  => 'MyScalar',
    }

would result in the following bindings:

    42->foo              -> [ MyInteger, MyNumber, MyScalar ]
    3.1415927->bar       -> [ MyNumber, MyScalar ]
    "Hello, world!"->baz -> [ MyScalar ]

Note that DEFAULT bindings take precedence over virtual type bindings, i.e.

    use autobox {
        UNIVERSAL => 'MyUniversal',
        DEFAULT   => 'MyDefault', # default SCALAR, ARRAY, HASH and CODE before UNIVERSAL
    }

is equivalent to:

  use autobox {
      INTEGER => [ 'MyDefault', 'MyUniversal' ],
      FLOAT   => [ 'MyDefault', 'MyUniversal' ], # ... etc.
  }

=head2 DEBUG

C<DEBUG> allows the autobox bindings for the current scope to be inspected,
either by dumping them to the console or passing them to a callback function.
This allows the computed bindings to be seen in "longhand".

The option is ignored if the value corresponding to the C<DEBUG> key is false.

If the value is a CODE ref, it is called with a reference to the hash
containing the computed bindings for the current scope.

Finally, if C<DEBUG> is true but not a CODE ref, the bindings are dumped
to STDERR.

Thus:

    use autobox DEBUG => 1, ...

or

    use autobox DEBUG => sub { ... }, ...

or

    sub my_callback ($) {
        my $hashref = shift;
        ...
    }

    use autobox DEBUG => \&my_callback, ...

=head1 METHODS

=head2 import

This method sets up autobox bindings for the current lexical scope. It can be used to implement
autobox extensions, i.e. lexically-scoped modules that provide autobox bindings for one or more
native types without requiring calling code to C<use autobox>.

This is done by subclassing autobox and overriding C<import>. This allows extensions to effectively
translate C<use MyModule> into a bespoke C<use autobox> call, e.g.:

    package String::Trim;

    use base qw(autobox);

    sub import {
        my $class = shift;

        $class->SUPER::import(
            STRING => 'String::Trim::String'
        );
    }

    package String::Trim::String;

    sub trim {
        my $string = shift;
        $string =~ s/^\s+//;
        $string =~ s/\s+$//;
        $string;
    }

    1;

Note that C<trim> is defined in an auxiliary class rather than in String::Trim itself to prevent
String::Trim's own methods (i.e. the methods it inherits from autobox) being exposed to C<STRING> types.

This module can now be used without a C<use autobox> statement to enable the C<trim> method in the current
lexical scope, e.g.:

    #!/usr/bin/env perl

    use String::Trim;

    print "  Hello, world!  "->trim();

=head1 UNIVERSAL METHODS FOR AUTOBOXED TYPES

=head2 autobox_class

autobox adds a single method to all autoboxed types: C<autobox_class>. This can be used to
call L<UNIVERSAL|UNIVERSAL> methods, i.e. C<can>, C<DOES>, C<import>, C<isa>, C<unimport> and C<VERSION>, e.g.

    if (sub { ... }->autobox_class->can('curry')) ...
    if (42->autobox_class->isa('SCALAR')) ...

Note: C<autobox_class> must B<always> be used when calling these methods. Calling them
directly on native types produces the same results as calling them with autobox disabled
e.g.:

    42->isa('NUMBER') # "" (interpreted as "42"->isa("NUMBER"))
    []->can('push')   # Error: Can't call method "can" on unblessed reference

=head1 EXPORTS

=head2 type

autobox includes an additional module, autobox::universal, which exports a single subroutine, C<type>.

This sub returns the type of its argument within autobox (which is essentially longhand for the type names
used within perl). This value is used by autobox to associate a method invocant with its designated classes, e.g.

    use autobox::universal qw(type);

    type("42")  # STRING
    type(42)    # INTEGER
    type(42.0)  # FLOAT
    type(undef) # UNDEF

autobox::universal is loaded automatically by autobox, and, as its name suggests, can be used to install
a universal C<type> method for autoboxed values, e.g.

    use autobox UNIVERSAL => 'autobox::universal';

    42->type        # INTEGER
    3.1415927->type # FLOAT
    %ENV->type      # HASH

=head1 CAVEATS

=head2 Performance

Calling

    "Hello, world!"->length()

is slightly slower than the equivalent method call on a string-like object, and significantly slower than

    length("Hello, world!")

=head2 Gotchas

=head3 Precedence

Due to Perl's precedence rules, some autoboxed literals may need to be parenthesized:

For instance, while this works:

    my $curried = sub { ... }->curry();

this doesn't:

    my $curried = \&foo->curry();

The solution is to wrap the reference in parentheses:

    my $curried = (\&foo)->curry();

The same applies for signed integer and float literals:

    # this works
    my $range = 10->to(1);

    # this doesn't work
    my $range = -10->to(10);

    # this works
    my $range = (-10)->to(10);

=head3 print BLOCK

Perl's special-casing for the C<print BLOCK ...> syntax (see L<perlsub>) means that C<print { expression() } ...>
(where the curly brackets denote an anonymous HASH ref) may require some further disambiguation:

    # this works
    print { foo => 'bar' }->foo();

    # and this
    print { 'foo', 'bar' }->foo();

    # and even this
    print { 'foo', 'bar', @_ }->foo();

    # but this doesn't
    print { @_ }->foo() ? 1 : 0;

In the latter case, the solution is to supply something
other than a HASH ref literal as the first argument
to C<print()>:

    # e.g.
    print STDOUT { @_ }->foo() ? 1 : 0;

    # or
    my $hashref = { @_ };
    print $hashref->foo() ? 1 : 0;

    # or
    print '', { @_ }->foo() ? 1 : 0;

    # or
    print '' . { @_ }->foo() ? 1 : 0;

    # or even
    { @_ }->print_if_foo(1, 0);

=head3 eval EXPR

Like most pragmas, autobox performs operations at compile time, and,
as a result, runtime string C<eval>s are not executed within its scope, i.e.
this doesn't work:

    use autobox;

    eval "42->foo";

The workaround is to use autobox within the C<eval>, e.g.

    eval <<'EOS';
        use autobox;
        42->foo();
    EOS

Note that the C<eval BLOCK> form works as expected:

    use autobox;

    eval { 42->foo() }; # OK

=head3 Operator Overloading

Operator overloading via the L<overload> pragma doesn't (automatically) work.
autobox works by lexically overriding the L<arrow operator|perlop/"The Arrow Operator">.
It doesn't bless native types into objects, so overloading - or any other kind of "magic"
which depends on values being blessed - doesn't apply.

=head1 VERSION

3.0.2

=head1 SEE ALSO

=over

=item * L<autobox::Core|autobox::Core>

=item * L<Moose::Autobox>

=item * L<perl5i|perl5i>

=item * L<Scalar::Properties|Scalar::Properties>

=back

=head1 AUTHOR

chocolateboy <chocolate@cpan.org>

=head1 COPYRIGHT AND LICENSE

Copyright (c) 2003-2024 by chocolateboy.

This library is free software; you can redistribute it and/or modify it under the
terms of the L<Artistic License 2.0|https://www.opensource.org/licenses/artistic-license-2.0.php>.

=cut
