Devel-REPL-InProcess
view release on metacpan or search on metacpan
lib/Devel/REPL/Client/AnyEvent/Connection.pm view on Meta::CPAN
package Devel::REPL::Client::AnyEvent::Connection;
use strict;
use warnings;
use AnyEvent::Handle;
use Scalar::Util qw(weaken);
use Term::ReadKey;
use constant {
EOT => "\x04",
};
sub new {
my ($class, %args) = @_;
my $self = bless {
handle => undef,
input => undef,
on_close => undef,
}, $class;
my $weak_self = $self;
weaken($weak_self);
my $handle = AnyEvent::Handle->new(
fh => $args{socket},
on_error => sub {
my ($handle, $fatal, $message) = @_;
$weak_self->{handle} = $weak_self->{watch} = undef;
$handle->destroy;
$weak_self->{on_close}->($weak_self)
if $weak_self->{on_close};
},
on_read => sub {
my ($handle) = @_;
syswrite *STDOUT, $handle->{rbuf};
substr $handle->{rbuf}, 0, length($handle->{rbuf}), '';
},
on_eof => sub {
my ($handle) = @_;
$weak_self->{handle} = $weak_self->{watch} = undef;
$handle->destroy;
$weak_self->{on_close}->($weak_self)
if $weak_self->{on_close};
},
);
my $watch = AnyEvent->io(
fh => \*STDIN,
poll => 'r',
cb => sub {
while (defined(my $key = ReadKey -1, \*STDIN)) {
$handle->push_write($key);
if ($key eq EOT) {
print STDOUT "^D\n";
$handle->push_shutdown;
}
}
},
);
$self->{handle} = $handle;
$self->{watch} = $watch;
return $self;
}
sub DESTROY {
my ($self) = @_;
$self->close;
}
sub on_close { $_[0]->{on_close} = $_[1] }
sub close {
my ($self) = @_;
$self->{handle}->destroy if $self->{handle} && !$self->{handle}->destroyed;
}
1;
( run in 0.864 second using v1.01-cache-2.11-cpan-39bf76dae61 )