FunctionalPerl
view release on metacpan or search on metacpan
lib/FP/Repl/StackPlus.pm view on Meta::CPAN
#
# Copyright (c) 2015 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
FP::Repl::StackPlus - Stack including lexical variables
=head1 SYNOPSIS
my $stack = FP::Repl::StackPlus->get($numbers_of_levels_to_skip);
# same as FP::Repl::Stack, but frames also have `lexicals`, a hash
# as delivered from PadWalker
=head1 DESCRIPTION
I'm pretty sure this is still re-inventing some wheel...
=head1 SEE ALSO
L<FP::Repl::Stack>, L<PadWalker>
=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 FP::Repl::StackPlus;
use strict;
use warnings;
use warnings FATAL => 'uninitialized';
{
package FP::Repl::Repl::StackPlusFrame;
use FP::Repl::Stack; # so that FP::Struct won't try to load
# FP/Repl/StackFrame.pm
use FP::Struct ["lexicals"], "FP::Repl::StackFrame";
# CAREFUL: equal stackframes still don't need to be the *same*
# stackframe!
sub equal {
my $s = shift;
my ($v) = @_;
die "not implemented (yet?)";
}
_END_
}
use PadWalker qw(peek_my);
# TODO/XXX: see comments in commit 'StackPlus: don't die in peek_my
# (HACK)'; this should be replaced with something clean /
# investigated.
our $maybe_peek_my = sub {
my ($skip) = @_;
my $res;
if (
eval {
$res = peek_my($skip);
1
}
)
{
$res
} else {
my $e = $@;
if ($e =~ /^Not nested deeply enough/i) {
undef
} else {
die $e
}
}
};
use FP::Struct [], "FP::Repl::Stack";
# XX ugly, modified COPY from FP::Repl::Stack
sub get {
my $class = shift;
my ($skip) = @_;
package DB; # needs to be outside loop or it won't work. Wow Perl.
my @frames;
while (my @vals = caller($skip)) {
my $subargs = [@DB::args];
# XX how to handle this?: "@DB::args might have
# information from the previous time "caller" was
# called" (perlfunc on 'caller')
push @frames,
FP::Repl::Repl::StackPlusFrame->new($subargs, @vals,
&$maybe_peek_my($skip + 2));
$skip++;
}
$class->new(\@frames);
}
*lexicals = &$FP::Repl::Stack::make_frame_accessor("lexicals");
*perhaps_lexicals = &$FP::Repl::Stack::make_perhaps_frame_accessor("lexicals");
_END_
( run in 0.688 second using v1.01-cache-2.11-cpan-39bf76dae61 )