=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 C<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 C<Foo> and C<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 C<Foo> and C<Bar> classes and ARRAY types to C<Baz>.
C<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 &c.) 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 &c.
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 => 'MyArray',
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' ], # ... &c.
=head2 DEBUG
C<DEBUG> exposes the current bindings for the scope in which C<use autobox> is called by means
of a callback, or a static debugging 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, then this sub 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 C<autobox> bindings for the current lexical scope. It can be used to implement
C<autobox> extensions i.e. lexically-scoped modules that provide C<autobox> bindings for one or more
native types without requiring calling code to C<use autobox>.
This is done by subclassing C<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 C<String::Trim> itself to prevent
C<String::Trim>'s own methods (i.e. the methods it inherits from C<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
C<autobox> adds a single method to all autoboxed types: C<autobox_class>. This can be used to
call C<can>, C<isa>, C<VERSION>, C<import> and C<unimport>. e.g.
if (sub { ... }->autobox_class->can('curry')) ...
if (42->autobox_class->isa('SCALAR')) ...
Note: C<autobox_class> should B<always> be used when calling these methods. The behaviour when
these methods are called directly on the native type e.g.:
42->can('foo')
42->isa('Bar')
42->VERSION
- is undefined.
=head1 EXPORTS
=head2 type
C<autobox> includes an additional module, C<autobox::universal>, which exports a single subroutine, C<type>.
This sub returns the type of its argument within C<autobox> (which is essentially longhand for the type names
used within perl). This value is used by C<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
C<autobox::universal> is loaded automatically by C<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, C<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 C<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
=head1 VERSION
2.85
=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
Copyright (c) 2003-2017, chocolateboy.
This module is free software. It may be used, redistributed
and/or modified under the same terms as Perl itself.
=cut