FunctionalPerl
view release on metacpan or search on metacpan
lib/FP/Repl/Repl.pm view on Meta::CPAN
)
}
our $use_warnings = q{use warnings; use warnings FATAL => 'uninitialized';};
sub eval_code {
my $self = shift;
@_ == 5 or fp_croak_arity 5;
my ($code, $in_package, $maybe_lexicals, $maybe_kept_results,
$maybe_lexical_persistence)
= @_;
# merge with previous results, if any
my $maybe_kept_results_hash = sub {
return unless $maybe_kept_results;
my %r;
for (my $i = 0; $i < @$maybe_kept_results; $i++) {
$r{ '$VAR' . ($i + 1) } = \($$maybe_kept_results[$i]);
}
\%r
};
$maybe_lexicals
= ($maybe_lexicals && $maybe_kept_results)
? hashset_union($maybe_lexicals, &$maybe_kept_results_hash)
: ($maybe_lexicals // &$maybe_kept_results_hash);
my $use_method_signatures
= $Method::Signatures::VERSION ? "use Method::Signatures" : "";
my $use_functional_parameters_
= $Function::Parameters::VERSION
? "use Function::Parameters ':strict'"
: "";
my $use_signatures = ($] >= 5.020) ? "use experimental 'signatures'" : "";
my $use_tail = $Sub::Call::Tail::VERSION ? "use Sub::Call::Tail" : "";
my $use_autobox = @FP::autobox::ISA ? "use FP::autobox" : "";
my $prelude
= "package "
. &$in_package() . ";"
. "use strict; "
. ($self->use_strict_vars ? "" : "no strict 'vars'; ")
. "$use_warnings; "
. "$use_method_signatures; $use_functional_parameters_; "
. "$use_signatures; $use_tail; $use_autobox; ";
if (my $lp = $maybe_lexical_persistence) {
my $allcode = $prelude . $code;
if (defined $maybe_lexicals) {
$lp->lexicals(hashset_union($lp->lexicals, $maybe_lexicals))
}
my $context = wantarray ? "list" : "scalar"; ## no critic
$lp->context($context);
WithRepl_eval { $lp->eval($allcode) }
} else {
my @v = sort keys %{ $maybe_lexicals // {} };
my $allcode
= $prelude
. (@v ? 'my (' . join(", ", @v) . '); ' : '') . 'sub {'
. $code . "\n" . '}';
my $thunk = &WithRepl_eval($allcode) // return;
PadWalker::set_closed_over($thunk, $maybe_lexicals)
if defined $maybe_lexicals;
WithRepl_eval { &$thunk() }
}
}
sub _completion_function {
my ($attribs, $package, $lexicals) = @_;
sub {
my ($text, $line, $start, $end) = @_;
my $part = substr($line, 0, $end);
#reset to the default before deciding upon it:
$attribs->{completion_append_character} = " ";
my @matches = do {
# arrow completion:
my ($pre, $varnam, $brace, $alreadywritten);
if (($pre, $varnam, $brace, $alreadywritten)
= $part =~ /(.*)\$(\w+)\s*->\s*([{\[]\s*)?(\w*)\z/s
or ($pre, $varnam, $brace, $alreadywritten)
= $part =~ /(.*\$)\$(\w+)(?:\s+|(?:\s*([{\[]\s*)(\w*)))\z/s)
{
# need to know the class of that thing
no strict 'refs';
my $r;
# try to get the value, or at least the package.
my $val = do {
if (my $ref = $$lexicals{ '$' . $varnam }) {
$$ref
} else {
my $v = ${ $package . "::" . $varnam };
if (defined $v) {
$v
} else {
# (if I could run code side-effect free... or
# compile-only and disassemble....) Try to
# parse the perl myself
if (
$part =~ /.* # force latest possible match (ok?)
(?:^|;)\s*
(?:(?:my|our)\s+)?
# ^ optional for no 'use strict'
\$$varnam
\s* = \s*
(?:new\w*\s+($PACKAGE)
|($PACKAGE)\s*->\s*new)
/sx
)
{
$r = $1;
1
} else {
0
}
}
}
};
( run in 1.904 second using v1.01-cache-2.11-cpan-39bf76dae61 )