NAME
BEGIN::Lift - Lift subroutine calls into the BEGIN phase
SYNOPSIS
package Cariboo;
use strict;
use warnings;
use BEGIN::Lift;
sub import {
my $caller = caller;
BEGIN::Lift::install(
($caller, 'extends') => sub {
no strict 'refs';
@{$caller . '::ISA'} = @_;
}
);
}
package Foo;
use Cariboo;
extends 'Bar';
# functionally equivalent to ...
# BEGIN { @ISA = ('Bar') }
DESCRIPTION
This module serves a very specific purpose, which is to provide a mechanism through which we can "lift" a given subroutine to be executed entirely within the BEGIN
phase of the Perl compiler and to leave no trace of itself in the RUN
phase.
FUNCTIONS
install( $package, $keyword_name, $keyword_handler )
This will install a lifted subroutine named $keyword_name
into the specified $package
. All calls to this the lifted subroutine will execute the $keyword_handler
immediately after parsing it.
If this subroutine is called outside of the BEGIN
phase, an error will be thrown. If there already exists a typeglob for $keyword_name
then an error will be thrown.
CAVEATS
All arguments to lifted subroutines must be BEGIN
time safe
This means they require no runtime initiatlization or access to runtime initialized variables (as they won't be initialized).
For instance, given a lifted subroutine called add
, this code is BEGIN
time safe because the arguments are numeric literals.
add( 1, 1 );
While this version is not safe because it relies on the @args
variable being initialized at runtime.
my @args = (1, 1);
add( @args );
PARSING ISSUES
Ideally we can (eventually) detect these situations and error accordingly so that this is no longer a burden to the user of this module, but instead just part of the normal operation of it.
Non-void context
If, for instance, a lifted sub is called such that the return value is to be assigned to a variable, such as:
my $x = my_lifted_sub();
It will not behave as expected, since my_lifted_sub
is evaluated entirely at BEGIN
time, the resulting value for $x
at RUN
time is undef
.
Expression context
If, for instance, a lifted sub is called within an expression where the return value is important, such as:
if ( my_lifted_sub() && 10 ) { ... }
It will not behave as expected, since my_lifted_sub
is evaluated entirely at BEGIN
time and has the value of undef
at runtime, the conditional will always fail.
Statement modifier context
If, for instance, a lifted sub call is guarded by a statement modifier, such as:
my_lifted_sub() if 0;
It will not behave as expected, since the lifted sub call is evaluated entirely at BEGIN
time the statement modifier has no affect at all and <my_lifted_sub> will always be executed.
SEE ALSO
- Devel::BeginLift
-
This does a similar thing, but does it via "some slightly insane perlguts magic", while this module has much the same goals, it will (hopefully) accomplish it with less insanity.
AUTHOR
Stevan Little <stevan@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2017 by Stevan Little.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.