package Dancer;
{
$Dancer::VERSION = '1.9999_01';
}
# ABSTRACT: Lightweight yet powerful web application framework
use strict;
use warnings;
use Carp;
use Data::Dumper;
use Dancer::Core::Runner;
use Dancer::Core::App;
use Dancer::FileUtils;
use Dancer::ModuleLoader;
#set version in dist.ini now
# but we still need a basic version for
# the tests
$Dancer::VERSION ||= '2.00';
our $AUTHORITY = 'SUKRIA';
my $api_version = 0;
sub VERSION {
my $class = shift;
$api_version = $_[0] if @_;
return $class->SUPER::VERSION(@_);
}
#
# private
#
my $runner;
sub runner {$runner}
sub import {
my ($class, @args) = @_;
my ($caller, $script) = caller;
strict->import;
utf8->import;
my @final_args;
my $syntax_only = 0;
my $as_script = 0;
foreach (@args) {
if ($_ eq ':moose') {
push @final_args, '!before' => 1, '!after' => 1;
}
elsif ($_ eq ':tests') {
push @final_args, '!pass' => 1;
}
elsif ($_ eq ':syntax') {
$syntax_only = 1;
}
elsif ($_ eq ':script') {
$as_script = 1;
}
elsif (substr($_, 0, 1) eq '!') {
push @final_args, $_, 1;
}
else {
push @final_args, $_;
}
}
scalar(@final_args) % 2
and die
"parameters to 'use Dancer' should be one of : 'key => value', ':moose', ':tests', ':script', or !<keyword>, where <keyword> is a DSL keyword you don't want to import";
my %final_args = @final_args;
$final_args{dsl} ||= 'Dancer::Core::DSL';
# never instanciated the runner, should do it now
if (not defined $runner) {
# TODO should support commandline options as well
$runner = Dancer::Core::Runner->new(caller => $script,);
}
my $local_libdir = Dancer::FileUtils::path($runner->location, 'lib');
Dancer::ModuleLoader->use_lib($local_libdir) if -d $local_libdir;
# the app object
my $app = Dancer::Core::App->new(
name => $caller,
environment => $runner->environment,
location => $runner->location,
runner_config => $runner->config,
postponed_hooks => $runner->postponed_hooks,
(api_version => int $api_version) x !!$api_version,
);
$api_version = 0; # reset variable for next 'use Dancer X' call
core_debug("binding import method to $caller");
_set_import_method_to_caller($caller);
# register the app within the runner instance
core_debug("binding app to $caller");
$runner->server->register_application($app);
core_debug("exporting DSL symbols for $caller");
# load the DSL, defaulting to Dancer::Core::DSL
Dancer::ModuleLoader->require($final_args{dsl})
or die "Couldn't require '" . $final_args{dsl} . "'\n";
my $dsl = $final_args{dsl}->new(app => $app);
$dsl->export_symbols_to($caller, \%final_args);
#
# # if :syntax option exists, don't change settings
# return if $syntax_only;
#
# $as_script = 1 if $ENV{PLACK_ENV};
#
# Dancer::GetOpt->process_args() if !$as_script;
}
sub _set_import_method_to_caller {
my ($caller) = @_;
my $import = sub {
my ($self, %options) = @_;
my $with = $options{with};
for my $key (keys %$with) {
$self->dancer_app->setting($key => $with->{$key});
}
};
{
no strict 'refs';
no warnings 'redefine';
*{"${caller}::import"} = $import;
}
}
sub core_debug {
my $msg = shift;
my (@stuff) = @_;
use Data::Dumper;
my $vars = @stuff ? Dumper(\@stuff) : '';
my ($package, $filename, $line) = caller;
return unless $ENV{DANCER_DEBUG_CORE};
chomp $msg;
print STDERR "core: $msg\n$vars";
}
1;
__END__
=pod
=head1 NAME
Dancer - Lightweight yet powerful web application framework
=head1 VERSION
version 1.9999_01
=head1 DESCRIPTION
This is the main module for the Dancer distribution. It contains logic for creating
a new Dancer application.
=head1 METHODS
=head2 my $runner=import;
This subroutine does most of the work.
First it imports strict and warnings.
Then it does the following for these import options:
=over 4
=item C<:moose>
No importing of C<before> and C<after> hooks into your namespace. This is to
prevent conflict with L<Moose> et al.
=item C<:tests>
No importing of C<pass> function. This is to prevent conflict with
L<Test::More> et al.
=item C<:syntax>
Imports syntax only instead of treating your code as a script with command line
parameter parsing and built-in web server.
=item C<:script>
Do not process arguments.
=back
It creates a new runner if one does not exist already.
It will then load additional libraries.
Then create a new Dancer app, of type L<Dancer::Core::App>.
Then it will export all the DSL symbols to the caller.
If any additional argument processing is needed, it will be done at this point.
=head1 FUNCTIONS
=head2 my $runner=runner();
Returns the current runner. It is of type L<Dancer::Core::Runner>.
=head2 core_debug
Output a message to STDERR and take further arguments as some data structures using
L<Data::Dumper>
=head1 AUDIENCE
This doc describes the Dancer application core and therefore meant for Dancer
core developers. If you're a user of Dancer, you should forget about this and
read the L<Dancer::Manual>.
You are also welcome to join our mailing list, and we're also on IRC: #dancer
on irc.perl.org.
=head1 AUTHOR
Dancer Core Developers
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2012 by Alexis Sukrieh.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut