package Evo;
use strict;
use warnings;
use Carp 'croak';
use Module::Load 'load';
use Evo::Util;
use feature 'say';


my $ARGS_RX = qr/[\s\(\[]*    ( [^\)\]]*?)    [\s\)\]]*/x;

sub _parse {
  my ($caller, $val) = @_;
  my $orig = $val;
  $val =~ tr/\n/ /;
  $val =~ s/^\s+|\s+$//g;

  $val =~ /^ ((\-|\:\:|\:)? $Evo::Util::RX_PKG_NOT_FIRST*) (.*)$/x;
  croak qq#Can't parse string "$orig"# unless $1;
  my ($class, $args) = (Evo::Util::resolve_package($caller, $1), $3);

  $args =~ s/^$ARGS_RX$/$1/;
  return ($class) unless $args;

  my @args = split /[,\s]+/, $args;
  ($class, @args);
}

sub import {
  shift;
  my ($target, $filename, $line) = caller;
  my @list = @_;
  unshift @list, '-Default' unless grep { $_ && $_ eq '-Default' } @list;

  @list = map { split ';', $_ } @list;
  foreach my $key (@list) {
    my ($class, @args) = _parse($target, $key);
    load($class);
    if (my $import = $class->can('import')) {
      Evo::Util::inject(package => $target, line => $line, filename => $filename, code => $import)
        ->($class, @args);
    }
    elsif (@args) {
      croak qq#Got import arguments but $class hasn't "import" method#;
    }
  }
}


our $VERSION = '0.0177';    # VERSION

1;

# ABSTRACT: Evo - the posmodern development framework

__END__

=pod

=encoding UTF-8

=head1 NAME

Evo - Evo - the posmodern development framework

=head1 VERSION

version 0.0177

=head1 DESCRIPTION

This framowerk opens new age of perl programming
It provides rewritten and postmodern features like

=over

=item *
Rewritten sexy L<Evo::Export>

=item *
Post modern component oriented programming L<Evo::Comp> instead of OO

=item *
Fast Event-Loop L<Evo::Loop> with unique feature zones (Not ready)

=item *
Fast non recursive L<Evo::Promises>, 100% Promises/Spec A compatible

=item *
Interesting L<Evo::Realm> design pattern, which is as handy as "Singleton" but without Sintleton's flaws.
It makes real thing that are considered impossible in other languages. For example, testing EventLoop timers without patching, separating flows for one loop and so on.
(ready but experimental and not documented)

=item *
Exception handling in pure perl: L<Evo::Eval>, "try catch" alternative. Like C<Try::Tiny>, but without it's bugs and much faster

=back

=head1 SYNOPSYS

  # enables strict, warnings, utf8, :5.22, signatured, postderef
  use Evo;

=head1 IMPORTING

Load Module and call it's C<import> method, emulating C<caller>. 

  use Evo 'Evo::SomeComp';
  use Evo 'Evo::SomeComp(function)';
  use Evo 'Evo::SomeComp(function,otherfunc)';
  use Evo 'Evo::SomeComp function1 function2';

Used to make package header shorter

  use Evo '-Eval *; My::App';

=head2 SHORTCUTS

  : => . (append to current)
  :: => .. (append to parent)
  - => Evo (append to Evo)

Import C<Evo::SomeComp> namespace

  use Evo '-SomeComp';

Import C<My::Ns::Foo::Rel>:

  package My::Ns::Foo;
  use Evo ':Bar';

Import C<My::Ns::Bar>:

  package My::Ns::Foo;
  use Evo '::Bar';

You can split import by C<;>

  package My::Ns::Foo;
  use Evo ':Bar bar1; :Baz baz1; Other::Foo foo1';

=head1 IMPORTS

With or without options, C<use Evo> loads L<Evo::Default>:

=head2 -Default

  use strict;
  use warnings;
  use feature ':5.22';
  use experimental 'signatures';
  use feature 'postderef';

I make some test and decided that using 5.22 and experimental features brings many benefits and worth it. This list will be expanded in the future, I hope

=head2 -Loaded

This marks inline or generated classes as loaded, so can be used with
C<require> or C<use>. So this code won't die

  require My::Inline;

  {
    package My::Inline;
    use Evo -Loaded;
    sub foo {'foo'}
  }

=head1 AUTHOR

alexbyk.com

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2016 by alexbyk.

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
