Acme-RPC
view release on metacpan or search on metacpan
lib/Acme/RPC.pm view on Meta::CPAN
use warnings;
our $VERSION = '0.01';
use B;
use B::Deparse;
use Continuity;
use IO::Handle;
# use Devel::Pointer;
use JSON;
use Data::Dumper;
use Devel::Caller 'caller_cv';
use PadWalker 'peek_sub';
use Scalar::Util 'blessed';
my $comment = <<'EOF';
Todo:
* Accept JSON as input too, for the parameters!
lib/Acme/RPC.pm view on Meta::CPAN
is causing confusion and grief.
Need a structure where for any given $node, $node->{chr(0)} is the (possible) object representing that node,
and $node->{everything else} is the stuff under it.
Then given a code ref, $node->{chr(0)} would be the code ref itself, and $node->{everything else} would be lexicals vars.
Given a stash like "foo::", $node->{chr(0)} would actually be \%{'foo::'} and $node->{everything else} would be stuff in that package.
* Rather than only taking oids to dump/call, also take a path in the tree.
* lazy=1 parameter where the last $tree is re-used rather than re-computed.
* Should switch to our own recurse logic from Data::Dumper to support these other things.
* action=dump on anything; in the case of a coderef, find its source on disc or else deparse it
* action=call on coderefs and blessed objects, with an args parameter, or arg1, arg2, arg3, etc, and a method parameter for blessed objs.
* json will croak if a reference contains objects in side it somewhere. Should handle this gracefully.
* Offer JSON output! Not just Data::Dumper. Do this for action=dump, action=call, and the default tree view.
* If Devel::Leak won't give us refs... have to do an Acme::State style crawl from main::,
but crawling into each sub and looking at its lexicals with PadWalker.
Could make for a nice tree view.
Would also make it easy to filter out the variables that hold refs.
* Maybe this should be called Acme::RPC.
* Actually crawl into code refs when recursing the output!
lib/Acme/RPC.pm view on Meta::CPAN
my $buf = B::Deparse->new()->coderef2text($ob);
$buf =~ s{<}{\<}g;
$request->print("<pre>$buf</pre>\n");
} else {
if($output and $output eq 'json') {
$ob = tryunref($ob, $request) or next;
$ob = tryunobject($ob, $request) or next;
$request->print(eval { to_json($ob, { ascii => 1, allow_unknown => 1, allow_blessed => 1, }, ) } || $@);
} else {
$ob = tryunref($ob, $request) or next;
$request->print("<pre>", Data::Dumper::Dumper($ob), "</pre>\n");
}
}
# Devel::Trace::trace('off') if exists $INC{'Devel/Trace.pm'};
} elsif($action eq 'call') {
my @ret;
my @args;
lib/Acme/RPC.pm view on Meta::CPAN
@ret = $ob->(@args);
} elsif(blessed($ob)) {
my $method = $request->param('method');
$ob->can($method) or do { $request->print("object does not define that method"); next; };
@ret = $ob->can($method)->($ob, @args);
}
if($output and $output eq 'json') {
request->print(eval { to_json(\@ret, { ascii => 1}, ) } || $@);
} else {
my $buf = Data::Dumper::Dumper(\@ret);
$request->print(qq{<pre>$buf</pre>\n});
}
for my $item (@ret) {
# add newly created items to the registry
$registry{0+$item} = $item if ref $item;
}
}
lib/Acme/RPC.pm view on Meta::CPAN
=item C<< / >>
(No parameter.)
=item C<< action=dump >>
Gives an index of packages, subroutines, variables in those subroutines, closures in those variables, and so on.
=item C<< output=json >>
Output a JavaScript datastructures (JSON) instead of Perl style L<Data::Dumper> or HTML.
The main index page otherwise prints out HTML (under the assumption that a human will be digging through it)
and other things mostly emit L<Data::Dumper> formatted text.
=item C<< oid=(number) >>
=item C<< path=/path/to/something >>
There are two ways to specify or reference an object: by it's C<oid> or by the path to navigate to it from the
main index screen.
JSON and HTML output from the main index screen specifies the oids of each item and the paths can be derived from
the labels in the graph.
With no action specified, it defaults to C<dump>.
lib/Acme/RPC.pm view on Meta::CPAN
Devel::Leak::CheckSV($lt);
# $buf =~ tr/A-Z/a-z/; print $buf;
close STDERR;
open STDERR, '>&', $olderr;
close $olderr;
$buf =~ s{(0x[a-f0-9]{6,})}{<a href="?oid=$1">$1</a>}g;
# $oid =~ m/^0x[0-9a-f]{8,}$/
# my $ob = Devel::Pointer::deref(hex($oid));
my $ob = Devel::Pointer::deref($oid);
my $buf = Data::Dumper::Dumper($ob);
# $buf =~ s{(0x[a-f0-9]{6,})}{<a href="?oid=$1">$1</a>}g;
$request->print(qq{<pre>$buf</pre>\n});
* Accepts posts as well, and handle by data type.
Posts to CODE refs run them with the arguments (attempt to reconstitute object references in the arguments... move to 0x style oids again
to support this).
Posts to object references (blessed things) invoke the named method in them (again, reconstituting the args).
Posts to scalars, arrays, hashes, etc merely replace their data.
( run in 0.338 second using v1.01-cache-2.11-cpan-a5abf4f5562 )