Permalink
Browse files

use synchronous REPLs throughout; use proper name and API roles for t…

…his too!
  • Loading branch information...
1 parent 523c79f commit 9a50f98db6a97d5532dac69b6791fc14c01d7c28 @jrockway committed Jun 8, 2010
@@ -1,9 +1,10 @@
use MooseX::Declare;
-class Stylish::REPL::Project {
+class Stylish::REPL::Project
+ with (AnyEvent::REPL::API::Sync, AnyEvent::REPL::API::Async) {
use Stylish::Project;
use AnyEvent::REPL;
- use AnyEvent::REPL::Types qw(REPL);
+ use AnyEvent::REPL::Types qw(SyncREPL AsyncREPL);
use AnyEvent::REPL::CoroWrapper;
use AnyEvent::Debounce;
use Coro;
@@ -31,7 +32,8 @@ class Stylish::REPL::Project {
has 'good_repl' => (
is => 'rw',
- isa => REPL,
+ isa => SyncREPL,
+ handles => 'AnyEvent::REPL::API::Sync',
lazy_build => 1,
);
@@ -78,50 +80,63 @@ class Stylish::REPL::Project {
method _build_good_repl {
my $r = $self->make_repl;
- async { $self->_setup_repl_pwd($r) }->join;
+ $self->_setup_repl_pwd($r);
return $r;
}
- method repl_eval(REPL $repl, Str $code) {
- my @result = $repl->do_eval($code, on_output => $self->on_output);
- return @result if wantarray;
- return join '', @result;
+ around do_eval(@args){
+ my $result = $self->$orig(@args);
+ chomp $result;
+ return $result;
+ }
+
+ method push_eval(@args) {
+ my $good_repl = $self->good_repl;
+ return $good_repl->can('push_eval') ?
+ $good_repl->push_eval(@args) :
+ $good_repl->repl->push_eval(@args);
}
- method repl_command(REPL $repl, Str $command, HashRef $args) {
- return $repl->do_command($command, $args);
+ method push_command(@args) {
+ my $good_repl = $self->good_repl;
+ return $good_repl->can('push_command') ?
+ $good_repl->push_command(@args) :
+ $good_repl->repl->push_command(@args);
}
- method _setup_repl_pwd(REPL $repl){
+
+ after kill { $self->change }
+
+ method _setup_repl_pwd(SyncREPL $repl){
my $dir = $self->project->root->resolve->absolute;
my $lib = $dir->subdir('lib');
- $self->repl_eval($repl, qq{chdir "\Q$dir\E";});
- $self->repl_eval($repl, qq{use lib "\Q$lib\E"});
+ $repl->do_eval(qq{chdir "\Q$dir\E";});
+ $repl->do_eval(qq{use lib "\Q$lib\E"});
}
- method _load_modules_in_repl(REPL $repl, Bool $strict_load? = 1){
+ method _load_modules_in_repl(SyncREPL $repl, Bool $strict_load? = 1){
my @modules = $self->project->get_libraries;
my $error = 'unknown error';
my $result = eval {
$self->_setup_repl_pwd($repl);
if ($strict_load) {
- $self->repl_eval($repl, qq{require "\Q$_\E"}) for @modules;
+ $repl->do_eval(qq{require "\Q$_\E"}) for @modules;
}
else {
- $self->repl_eval($repl, qq{eval { require "\Q$_\E" }}) for @modules;
+ $repl->do_eval(qq{eval { require "\Q$_\E" }}) for @modules;
}
- return $self->repl_eval($repl, qq{2 + 2});
+ return $repl->do_eval(qq{2 + 2});
};
$error = $@ if $@;
return $repl if defined $result && $result eq '4';
die "Modules failed to load in the new REPL: $error";
}
- method _transfer_lexenv(REPL $from, REPL $to){
+ method _transfer_lexenv(SyncREPL $from, SyncREPL $to){
my ($fh, $filename) = tempfile();
- $self->repl_command($from, 'save_state', { filename => $filename });
- $self->repl_command($to, 'restore_state', { filename => $filename });
+ $from->do_command( 'save_state', { filename => $filename } );
+ $to->do_command( 'restore_state', { filename => $filename } );
close $fh;
unlink $filename;
@@ -147,20 +162,5 @@ class Stylish::REPL::Project {
};
}
- method do_eval(Str $code, Bool $chomp? = 1){
- my $result = $self->repl_eval($self->good_repl, $code);
- chomp $result if $chomp;
- return $result;
- }
-
- method push_eval(@args){
- $self->good_repl->push_eval(@args);
- }
-
method BUILD { $self->change }
-
- method kill(Int $num? = 9) {
- $self->good_repl->kill($num);
- $self->change;
- }
}
@@ -2,12 +2,14 @@ use MooseX::Declare;
class Stylish::Server::Component::REPL with Stylish::Server::Component {
use MooseX::Types::Moose qw(Str Maybe HashRef Int);
- use Stylish::Types qw(REPL);
+ use AnyEvent::REPL::Types qw(SyncREPL);
use AnyEvent::REPL;
+ use AnyEvent::REPL::CoroWrapper;
+ use Try::Tiny;
has 'repls' => (
is => 'ro',
- isa => HashRef[REPL],
+ isa => HashRef[SyncREPL],
default => sub { +{} },
traits => ['Hash'],
handles => {
@@ -19,6 +21,15 @@ class Stylish::Server::Component::REPL with Stylish::Server::Component {
},
);
+ around add_repl(Str $name, $repl){
+ return $self->$orig(
+ $name,
+ $repl->does('AnyEvent::REPL::API::Async')
+ ? AnyEvent::REPL::CoroWrapper->new( repl => $repl )
+ : $repl,
+ );
+ }
+
before get_repl(Str $repl_name){
# make REPLs auto-vivify
$self->add_repl($repl_name, AnyEvent::REPL->new)
@@ -69,19 +80,20 @@ class Stylish::Server::Component::REPL with Stylish::Server::Component {
method repl_eval(Str :$name, Str :$code, CodeRef :$response_cb){
my $repl = $self->get_repl($name);
- my $done = Coro::rouse_cb;
my $is_success = 0;
- $repl->push_eval(
- $code,
- on_error => $done,
- on_result => sub { $is_success = 1; $done->(@_) },
- on_output => sub { $response_cb->('repl_output', {
- data => join('', @_),
- repl => $name,
- })},
- );
+ my $result = try {
+ my $r = $repl->do_eval(
+ $code,
+ on_output => sub { $response_cb->('repl_output', {
+ data => join('', @_),
+ repl => $name,
+ })},
+ );
+ $is_success = 1;
+ return $r;
+ } catch { $_ };
- return { success => $is_success, result => join('', Coro::rouse_wait) };
+ return { success => $is_success, result => $result };
}
method write_stdin(Str :$name, Str :$input){
View
@@ -1,6 +1,6 @@
use MooseX::Declare;
-class Stylish::Test::REPL {
+class Stylish::Test::REPL with AnyEvent::REPL::API::Sync {
use Stylish::Test::Recorder;
use Coro;
use Storable;
@@ -56,19 +56,14 @@ class Stylish::Test::REPL {
return Stylish::Test::Recorder->new;
}
- method push_eval(Str $code, CodeRef :$on_output?){
- $on_output ||= sub {};
- return $self->do_eval($code, on_output => $on_output);
- }
-
method test_eval(Str $code, CodeRef :$on_output?){
$on_output ||= sub {};
my ($fh, $filename) = tempfile();
$self->do_command( save_state => { filename => $filename } );
my $lexenv = retrieve($filename)->{context}{_};
- my $result = $self->push_eval($code, on_output => $on_output);
+ my $result = $self->do_eval($code, on_output => $on_output);
$self->do_one_test($lexenv, $code, $result);
return $result;
}
@@ -1,19 +1,18 @@
use MooseX::Declare;
# export test script to eval'd TAP
-class Stylish::Test::Writer::Run {
+class Stylish::Test::Writer::Run with AnyEvent::REPL::API::Sync {
use AnyEvent::REPL;
- use Stylish::Types qw(REPL);
+ use AnyEvent::REPL::Types qw(SyncREPL);
use Coro::Util::Rouse qw(rouse_cb rouse_wait);
use TAP::Parser;
has 'repl' => (
is => 'ro',
- isa => REPL,
+ isa => SyncREPL,
lazy_build => 1,
- handles => {
- _push_eval => 'push_eval',
- },
+ coerce => 1,
+ handles => 'AnyEvent::REPL::API::Sync',
);
has 'tap_accumulator' => (
@@ -34,22 +33,13 @@ class Stylish::Test::Writer::Run {
$self->run_use_command('Test::More');
}
- method push_eval(Str $code){
- my ($ok, $err) = rouse_cb;
- # print "# $code\n";
- $self->_push_eval(
- $code,
- on_output => sub { $self->accumulate_tap( $_[0] ) if $_[0] },
- on_error => $err,
- on_result => $ok,
- );
-
- return rouse_wait;
+ around do_eval(@args){
+ $self->$orig(@args, on_output => sub { $self->accumulate_tap($_[0]) });
}
method run(ArrayRef $script){
- $self->push_eval('delete $_REPL->{lexical_environment}');
- $self->push_eval('Test::Builder->new->reset');
+ $self->do_eval('delete $_REPL->{lexical_environment}');
+ $self->do_eval('Test::Builder->new->reset');
$self->clear_tap_accumulator;
for my $step (@$script) {
@@ -58,7 +48,7 @@ class Stylish::Test::Writer::Run {
$self->run_command(@$step);
}
- $self->push_eval('done_testing');
+ $self->do_eval('done_testing');
my $parser = TAP::Parser->new({
tap => $self->captured_tap,
@@ -82,18 +72,18 @@ class Stylish::Test::Writer::Run {
method run_use_command(Str $module, Str $args?){
$args ||= "";
- $self->push_eval("use $module $args");
+ $self->do_eval("use $module $args");
}
method run_bind_command(Str $var, Any $val) {
- $self->push_eval("my $var = ". $self->escape_for_eval($val));
+ $self->do_eval("my $var = ". $self->escape_for_eval($val));
}
method run_set_command(Str $var, Any $val) {
- $self->push_eval("$var = ". $self->escape_for_eval($val));
+ $self->do_eval("$var = ". $self->escape_for_eval($val));
}
method run_test_command(Str $got_var, Any $expected) {
- $self->push_eval("is_deeply $got_var, ". $self->escape_for_eval($expected));
+ $self->do_eval("is_deeply $got_var, ". $self->escape_for_eval($expected));
}
}
View
@@ -2,14 +2,12 @@ package Stylish::Types;
use strict;
use warnings;
-use MooseX::Types -declare => [qw/REPL Type Command Component Components/];
+use MooseX::Types -declare => [qw/Type Command Component Components/];
use MooseX::Types::Moose qw(CodeRef HashRef ArrayRef Str Object);
use MooseX::Types::Structured qw(Dict Optional);
class_type Type, { class => 'Moose::Meta::TypeConstraint' };
-duck_type REPL, ['push_eval'];
-
subtype Command, as Dict[
name => Str,
args => Optional[HashRef[Type]],
View
@@ -8,7 +8,7 @@ use Stylish::Server::Component::REPL;
my $repls = Stylish::Server::Component::REPL->new;
async {
- isa_ok $repls->get_repl('test'), 'AnyEvent::REPL';
+ isa_ok $repls->get_repl('test'), 'AnyEvent::REPL::CoroWrapper';
is_deeply $repls->repl_eval(
name => 'new_repl',
code => '2 + 2',
View
@@ -10,7 +10,7 @@ my $repl = Stylish::Test::REPL->new;
ok $repl;
async {
- $repl->push_eval('my $foo = 42');
+ $repl->do_eval('my $foo = 42');
$repl->test_eval('$foo + 1');
$repl->test_eval('$foo == 42');
}->join;

0 comments on commit 9a50f98

Please sign in to comment.