From: Matt S Trout Date: Thu, 17 May 2012 20:52:45 +0000 (+0000) Subject: working module sending X-Git-Tag: v0.001001~59 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=scpubgit%2FObject-Remote.git;a=commitdiff_plain;h=542d5b5ca3990695be389d0d497883876c189486 working module sending --- diff --git a/lib/Object/Remote.pm b/lib/Object/Remote.pm index a815501..c68cc8e 100644 --- a/lib/Object/Remote.pm +++ b/lib/Object/Remote.pm @@ -21,6 +21,7 @@ sub BUILD { my ($self, $args) = @_; unless ($self->id) { die "No id supplied and no class either" unless $args->{class}; + ref($_) eq 'HASH' and $_ = [ %$_ ] for $args->{args}; $self->_set_id( $self->_await( $self->connection->send( diff --git a/lib/Object/Remote/ModuleLoader.pm b/lib/Object/Remote/ModuleLoader.pm new file mode 100644 index 0000000..2c9f98e --- /dev/null +++ b/lib/Object/Remote/ModuleLoader.pm @@ -0,0 +1,46 @@ +package Object::Remote::ModuleLoader; + +BEGIN { + package Object::Remote::ModuleLoader::Hook; + use Moo; + has sender => (is => 'ro', required => 1); + + # unqualified INC forced into package main + sub Object::Remote::ModuleLoader::Hook::INC { + my ($self, $module) = @_; + if (my $code = $self->sender->source_for($module)) { + open my $fh, '<', \$code; + return $fh; + } + return; + } +} + +use Moo; + +has module_sender => (is => 'ro', required => 1); + +has inc_hook => (is => 'lazy'); + +sub _build_inc_hook { + my ($self) = @_; + Object::Remote::ModuleLoader::Hook->new(sender => $self->module_sender); +} + +sub BUILD { shift->enable } + +sub enable { + push @INC, shift->inc_hook; + return; +} + +sub disable { + my ($self) = @_; + my $hook = $self->inc_hook; + @INC = grep $_ ne $hook, @INC; + return; +} + +sub DEMOLISH { $_[0]->disable unless $_[1] } + +1; diff --git a/lib/Object/Remote/ModuleSender.pm b/lib/Object/Remote/ModuleSender.pm new file mode 100644 index 0000000..87f75f1 --- /dev/null +++ b/lib/Object/Remote/ModuleSender.pm @@ -0,0 +1,27 @@ +package Object::Remote::ModuleSender; + +use Config; +use File::Spec; +use List::Util qw(first); +use Moo; + +has dir_list => (is => 'lazy'); + +sub _build_dir_list { + my %core = map +($_ => 1), @Config{qw(privlibexp archlibexp)}; + [ grep !/$Config{archname}$/, grep !$core{$_}, @INC ]; +} + +sub source_for { + my ($self, $module) = @_; + my ($found) = first { -f $_ } + map File::Spec->catfile($_, $module), + @{$self->dir_list}; + die "Couldn't find ${module} in remote \@INC. dir_list contains:\n" + .join("\n", @{$self->dir_list}) + unless $found; + open my $fh, '<', $found or die "Couldn't open ${found} for ${module}: $!"; + return do { local $/; <$fh> }; +} + +1; diff --git a/t/sender.t b/t/sender.t new file mode 100644 index 0000000..8916297 --- /dev/null +++ b/t/sender.t @@ -0,0 +1,37 @@ +use strictures 1; +use Test::More; + +use Object::Remote::Connector::Local; +use Object::Remote; +use Object::Remote::ModuleSender; + +$ENV{PERL5LIB} = join( + ':', ($ENV{PERL5LIB} ? $ENV{PERL5LIB} : ()), qw(lib) +); + +my $connection = Object::Remote::Connector::Local->new->connect; + +my $ms = Object::Remote::ModuleSender->new( + dir_list => [ 't/lib' ] +); + +my $ml = Object::Remote->new( + connection => $connection, + class => 'Object::Remote::ModuleLoader', + args => { module_sender => $ms }, +); + +my $proxy = Object::Remote->new( + connection => $connection, + class => 'ORTestClass' +)->proxy; + +isnt($$, $proxy->pid, 'Different pid on the other side'); + +is($proxy->counter, 0, 'Counter at 0'); + +is($proxy->increment, 1, 'Increment to 1'); + +is($proxy->counter, 1, 'Counter at 1'); + +done_testing;