FunctionalPerl

 view release on metacpan or  search on metacpan

lib/Chj/Serialize.pm  view on Meta::CPAN

#
# Copyright (c) 2015-2019 Christian Jaeger, copying@christianjaeger.ch
#
# This is free software, offered under either the same terms as perl 5
# or the terms of the Artistic License version 2 or the terms of the
# MIT License (Expat version). See the file COPYING.md that came
# bundled with this file.
#

=head1 NAME

Chj::Serialize

=head1 SYNOPSIS

=head1 DESCRIPTION


=head1 NOTE

This is alpha software! Read the status section in the package README
or on the L<website|http://functional-perl.org/>.

=cut

package Chj::Serialize;
use strict;
use warnings;
use warnings FATAL => 'uninitialized';
use Exporter "import";

our @EXPORT      = qw(new_Serialize_Closure);
our @EXPORT_OK   = qw();
our %EXPORT_TAGS = (all => [@EXPORT, @EXPORT_OK]);

use Chj::TEST;

{

    package Chj::Serializable::Closure;
    use FP::Struct ["env", "code_id"], 'FP::Struct::Show', 'FP::Abstract::Pure';
    _END_
}

{

    package Chj::Serialize::Closure;

    use PadWalker qw(closed_over set_closed_over);
    use FP::Repl::WithRepl qw(WithRepl_eval);
    use B::Deparse;
    use FP::Predicates ":all";

    our $deparse = B::Deparse->new("-p", "-l", "-q");

    use FP::Struct [
        [\&is_hash,     "_closure_generator_code_to_id"],
        [\&is_hash,     "_id_to_closure_generator_code"],
        [\&is_hash,     "_id_to_closure_generator"],
        [\&is_natural0, "current_id"]
        ],
        'FP::Struct::Show';

    sub next_id {
        my ($self) = @_;
        $$self{current_id}++
    }

    sub id_to_closure_generator_code {
        my ($self, $id) = @_;
        $$self{_id_to_closure_generator_code}{$id} // die "unknown code_id $id";
    }

    sub id_to_closure_generator {
        my ($self, $id) = @_;
        $$self{_id_to_closure_generator}{$id}
            //= &WithRepl_eval($self->id_to_closure_generator_code($id))
            // die "eval error: $@";

        #XX oh, want a WithRepl_xeval ?
    }

    sub serializable {
        my ($self, $fn) = @_;

        my $env  = closed_over($fn);
        my $code = $deparse->coderef2text($fn);

        my $vars = [sort keys %$env];

        my $closure_generator_code
            = 'sub { my (' . join(",", @$vars) . ') = @_; sub ' . $code . ' }';

        # use this as key right now.

        my $id = $$self{_closure_generator_code_to_id}{$closure_generator_code}
            //= do {
            my $id = $self->next_id;
            $$self{_id_to_closure_generator_code}{$id}
                = $closure_generator_code;
            $id
            };

        # XX exclude web server handle (request) etc. [hw btw in schem? xhu]

        Chj::Serializable::Closure->new($env, $id);
    }

    sub executable {



( run in 2.501 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )