Devel-Main
view release on metacpan or search on metacpan
lib/Devel/Main.pm view on Meta::CPAN
# ABSTRACT: Syntactic sugar for a script's main routine
use strict;
use warnings;
package Devel::Main;
our $VERSION = 0.005;
sub import {
my $class = shift;
@_ = 'main' unless @_;
my $opts = ref($_[0]) ? shift : {};
my $caller = $opts->{into} // scalar(caller($opts->{into_level} // 0));
while (@_) {
my $name = shift;
my $args = ref($_[0]) ? shift : {};
my $gen = $class->can("$name\_generator")
or do { require Carp; Carp::croak("$class does not export sub '$name'") };
my $code = $gen->( $class, $name, $args );
my $as = join '', grep defined, (
$args->{ -prefix },
($args->{ -as } // $name),
$args->{ -suffix },
);
no strict 'refs';
*{"$caller\::$as"} = $code;
}
}
sub main_generator {
my ( $class, $name, $args ) = @_;
my $run_sub_name = $args->{'run_sub_name'} // "run_$name";
my $exit = $args->{'exit'} // 1;
return sub (&) {
my ($main_sub) = @_;
# If we're called from a script, run main and exit
if ( !defined caller(1) ) {
$main_sub->();
exit(0) if $exit;
}
# Otherwise, create a sub that turns its arguments into @ARGV
else {
no strict 'refs';
my $package = caller;
*{"${package}::$run_sub_name"} = sub {
local @ARGV = @_;
return $main_sub->();
};
# Return 1 to make the script pass 'require'
return 1;
}
};
}
1;
__END__
=pod
=head1 NAME
Devel::Main - Syntactic sugar for a script's main routine
=head1 VERSION
version 0.005
=head1 SYNOPSIS
use Devel::Main 'main';
main {
# Your main routine goes here
};
=head1 DESCRIPTION
This module provides a clean way of specifying your script's main routine.
=head1 METHODS
=head2 main()
Declares your script's main routine. Exits when done.
If, instead of executing your script, you load it with C<use> or C<require>, C<main> creates a subroutine named C<run_main> in the current package. You can then call this subroutine to run your main routine. Arguments passed to this subroutine will o...
Example:
require './my_script.pl';
run_main( 'foo' ); # Calls the main routine with @ARGV = ('foo')
If you alias the 'main' routine to another name, the "run" method will also be aliased. For example, if 'my_script.pl' had said:
use Devel::Main main => { -as => 'primary' };
primary {
# Main code here
};
then the installed subroutine would be called 'run_primary'.
You can also control whether or not the script exits after the main routine via the import parameter 'exit'.
( run in 0.554 second using v1.01-cache-2.11-cpan-5c0b1e786e0 )