package Evo::Lib;
use Evo '-Export *', -Util, 'Carp croak';
use Time::HiRes qw(CLOCK_MONOTONIC clock_gettime);

PATCH: {
  no warnings 'once';
  *Evo::Lib::debug        = *Evo::Util::debug{CODE};
  *Evo::Lib::monkey_patch = *Evo::Util::monkey_patch{CODE};
}

export qw(debug context_result monkey_patch);

my $HAS_M_TIME = eval { clock_gettime(CLOCK_MONOTONIC); 1 };

export_anon steady_time => $HAS_M_TIME
  ? sub { clock_gettime(CLOCK_MONOTONIC); }
  : \&Time::HiRes::time;

sub context_result($) {
  return unless $_[0];
  return if !defined $_[0][0];
  $_[0][0] ? (@{$_[0][1]}) : $_[0][1];
}

sub context_run : Export {
  my ($context, $fn) = (shift, pop);
  my $res = [$context];    # 0 is want
  do { $fn->(@_); return $res } if !defined $context;
  $res->[1] = $context ? [$fn->(@_)] : $fn->(@_);
  return $res;
}

sub eval_context_run : Export {
  my ($context, $fn) = (shift, pop);
  local $@;
  return (scalar eval { context_run($context, @_, $fn) }, $@);
}

sub ws_combine : Export {
  return unless @_;
  return $_[0] if @_ == 1;
  my @wrappers = reverse @_;
  sub {
    my $w = $_[0];
    $w = $_->($w) for @wrappers;
    $w;
  };
}

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

Evo::Lib

=head1 VERSION

version 0.0172

=head2 eval_context_run

Run subroutine with given context

  my ($res, $err) = eval_context_run(wantarray, @args, sub {...});
  die $err if !$res; # don't use if $err
  return context_result($res);

Localize $@ and evaluate subroutine. Don't test C<ERR> because it will remain
untouched. Also don't test C<$err>, because it contains a previous C<$@> which
can be an instance of a class with overload.

C<$res> is always true, if no exception raised, of undefined, if an exception
occured

=head2 context_run 

  my $res = context_run wantarray, @args, sub {};
  return context_result($res);

=head2 ERR

  local $@;
  eval { die "foo" };
  die $@ if ERR;

Exists because $@ can be an instance of a class with overload. Returns a
reference to the $@ (true) if (ref $@ || $@) or false

=head1 AUTHOR

alexbyk.com

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2015 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
