$client in tak repl
[scpubgit/Tak.git] / lib / Tak / EvalService.pm
1 package Tak::EvalService;
2
3 use Eval::WithLexicals;
4 use Data::Dumper::Concise;
5 use Capture::Tiny qw(capture);
6 use Moo;
7
8 with 'Tak::Role::Service';
9
10 has 'eval_withlexicals' => (is => 'lazy');
11
12 has 'service_client' => (is => 'ro', predicate => 'has_service_client');
13
14 sub _build_eval_withlexicals {
15   my ($self) = @_;
16   Eval::WithLexicals->new(
17     $self->has_service_client
18       ? (lexicals => { '$client' => \($self->service_client) })
19       : ()
20   );
21 }
22
23 sub handle_eval {
24   my ($self, $perl) = @_;
25   unless ($perl) {
26     die [ mistake => eval_input => "No code supplied" ];
27   }
28   if (my $ref = ref($perl)) {
29     die [ mistake => eval_input => "Code was a ${ref} reference" ];
30   }
31   my ($ok, @ret);
32   my ($stdout, $stderr);
33   if (eval {
34     ($stdout, $stderr) = capture {
35       @ret = $self->eval_withlexicals->eval($perl);
36     };
37     1
38   }) {
39     $ok = 1;
40   } else {
41     ($ok, @ret) = (0, $@);
42   }
43   my $dumped_ret;
44   unless (eval { $dumped_ret = Dumper(@ret); 1 }) {
45     $dumped_ret = "Error dumping ${\($ok ? 'result' : 'exception')}: $@";
46     $ok = 0;
47   }
48   return {
49     stdout => $stdout, stderr => $stderr,
50     ($ok ? 'return' : 'exception') => $dumped_ret
51   };
52 }
53
54 1;