nix-archive-1(type directoryentry(namebinnode(type directoryentry(name.tinyrepl-realnode(typeregular executablecontentsk#!/gnu/store/v6bivyjbg6bj07s8iqfzdm6hpvypc0p1-perl-5.36.0/bin/perl use strictures 1; use Eval::WithLexicals; use Term::ReadLine; use Data::Dumper; use Getopt::Long; GetOptions( "plugin=s" => \my @plugins ); $SIG{INT} = sub { warn "SIGINT\n" }; { package Data::Dumper; no strict 'vars'; $Terse = $Indent = $Useqq = $Deparse = $Sortkeys = 1; $Quotekeys = 0; } my $eval = @plugins ? Eval::WithLexicals->with_plugins(@plugins)->new : Eval::WithLexicals->new; my $read = Term::ReadLine->new('Perl REPL'); while (1) { my $line = $read->readline('re.pl$ '); exit unless defined $line; my @ret; eval { local $SIG{INT} = sub { die "Caught SIGINT" }; @ret = $eval->eval($line); 1; } or @ret = ("Error!", $@); print Dumper @ret; } __END__ =head1 NAME tinyrepl - Tiny REPL =head1 SYNOPSIS $ tinyrepl re.pl$ "s" x 5 "sssss" re.pl$ exit $ tinyrepl --plugin HintPersistence =head1 DESCRIPTION tinyrepl is a minimal pure-Perl REPL. It is just a small wrapper around L. =head1 OPTIONS =over 4 =item C<--plugin=> Loads a plugin into the REPL. See L. =back =head1 SUPPORT See L for support and contact information. =head1 AUTHORS See L for authors. =head1 COPYRIGHT AND LICENSE See L for the copyright and license. =cut ))entry(nametinyreplnode(typeregular executablecontents#!/gnu/store/x47i4yafqxdav838aykda9c2hhhn9sa4-bash-minimal-5.1.16/bin/bash export PERL5LIB="/gnu/store/v6bivyjbg6bj07s8iqfzdm6hpvypc0p1-perl-5.36.0/lib/perl5/site_perl:/gnu/store/hz9qxdhn2mv7zjl3billixr0jlbiz1c2-perl-moo-1.007000/lib/perl5/site_perl:/gnu/store/vblwn08484d3ffzz0lbimrf4irxbfc2y-perl-strictures-1.005005/lib/perl5/site_perl:/gnu/store/iw3s761pp06jp77i20vs88cksjphm45y-perl-role-tiny-1.003004/lib/perl5/site_perl:/gnu/store/5s5snr3ldx50i00x5x9qi3sqi22rnh38-perl-module-runtime-0.016/lib/perl5/site_perl:/gnu/store/iqn06zqvb8y7j18bvgh9k0xagfphcm6s-perl-import-into-1.002005/lib/perl5/site_perl:/gnu/store/rxcv07hm8jnyv0v9pb6732jhd1z33xmp-perl-devel-globaldestruction-0.14/lib/perl5/site_perl:/gnu/store/cwv18h6k4yk48qpvdwby8bg960j2c6b6-perl-class-xsaccessor-1.19/lib/perl5/site_perl:/gnu/store/cagqm2pmfzxnyc7h14r612x6g12csd96-perl-class-method-modifiers-2.13/lib/perl5/site_perl:/gnu/store/5b66jfmj31yaclkckkcvj3i3i5fl680a-perl-sub-exporter-progressive-0.001013/lib/perl5/site_perl:/gnu/store/00n86di6yhhrbcrvpiv1ag0099sk4pcn-perl-eval-withlexicals-1.003006/lib/perl5/site_perl${PERL5LIB:+:}$PERL5LIB" exec -a "$0" "/gnu/store/00n86di6yhhrbcrvpiv1ag0099sk4pcn-perl-eval-withlexicals-1.003006/bin/.tinyrepl-real" "$@" ))))entry(namelibnode(type directoryentry(nameperl5node(type directoryentry(name site_perlnode(type directoryentry(name5.36.0node(type directoryentry(nameEvalnode(type directoryentry(name WithLexicalsnode(type directoryentry(nameWithHintPersistence.pmnode(typeregularcontentsR package Eval::WithLexicals::WithHintPersistence; use Moo::Role; use Sub::Quote; our $VERSION = '1.003006'; # v1.3.6 $VERSION = eval $VERSION; has hints => ( is => 'rw', default => quote_sub q{ {} }, ); has _first_eval => ( is => 'rw', default => quote_sub q{ 1 }, ); around eval => sub { my $orig = shift; my($self) = @_; local *Eval::WithLexicals::Cage::capture_hints; local $Eval::WithLexicals::Cage::hints = { %{$self->hints} }; my @ret = $orig->(@_); $self->hints({ Eval::WithLexicals::Cage::capture_hints() }); @ret; }; # XXX: Sub::Quote::capture_unroll without 'my' use B(); sub _capture_unroll_global { my ($from, $captures, $indent) = @_; join( '', map { /^([\@\%\$])/ or die "capture key should start with \@, \% or \$: $_"; (' ' x $indent).qq{${_} = ${1}{${from}->{${\B::perlstring $_}}};\n}; } keys %$captures ); } sub setup_code { my($self) = @_; # Only run the prelude on the first eval, hints will be set after # that. if($self->_first_eval) { $self->_first_eval(0); return $self->prelude; } else { # Seems we can't use the technique of passing via @_ for code in a BEGIN # block return q[ BEGIN { ], _capture_unroll_global('$Eval::WithLexicals::Cage::hints', $self->hints, 2), q[ } ], } }; around capture_code => sub { my $orig = shift; my($self) = @_; ( q{ sub Eval::WithLexicals::Cage::capture_hints { my ($hints, %hints, $warn_bits); BEGIN { no warnings 'closure'; $hints = $^H; %hints = %^H; $warn_bits = ${^WARNING_BITS}; } return ( q{$^H} => \$hints, q{%^H} => \%hints, q{${^WARNING_BITS}} => \$warn_bits, ); } }, $orig->(@_) ) }; 1; __END__ =head1 NAME Eval::WithLexicals::WithHintPersistence - Persist compile hints between evals =head1 SYNOPSIS use Eval::WithLexicals; my $eval = Eval::WithLexicals->with_plugins("HintPersistence")->new; =head1 DESCRIPTION Persist pragams and other compile hints between evals (for example the L and L flags in effect). Saves and restores the C<$^H> and C<%^H> variables. =head1 METHODS =head2 hints $eval->hints('$^H') Returns the internal hints hash, keys are C<$^H> and C<%^H> for the hint bits and hint hash respectively. =head1 SUPPORT See L for support and contact information. =head1 AUTHORS See L for authors. =head1 COPYRIGHT AND LICENSE See L for the copyright and license. =cut ))))entry(nameWithLexicals.pmnode(typeregularcontentspackage Eval::WithLexicals; use Moo; use Moo::Role (); use Sub::Quote; our $VERSION = '1.003006'; # v1.3.6 $VERSION = eval $VERSION; has lexicals => (is => 'rw', default => quote_sub q{ {} }); { my %valid_contexts = map +($_ => 1), qw(list scalar void); has context => ( is => 'rw', default => quote_sub(q{ 'list' }), isa => sub { my ($val) = @_; die "Invalid context type $val - should be list, scalar or void" unless $valid_contexts{$val}; }, ); } has in_package => ( is => 'rw', default => quote_sub q{ 'Eval::WithLexicals::Scratchpad' } ); has prelude => ( is => 'rw', default => quote_sub q{ 'use strictures 1;' } ); sub with_plugins { my($class, @names) = @_; Moo::Role->create_class_with_roles($class, map "Eval::WithLexicals::With$_", @names); } sub setup_code { my($self) = @_; $self->prelude; } sub capture_code { ( qq{ BEGIN { Eval::WithLexicals::Util::capture_list() } } ) } sub eval { my ($self, $to_eval) = @_; local *Eval::WithLexicals::Cage::current_line; local *Eval::WithLexicals::Cage::pad_capture; local *Eval::WithLexicals::Cage::grab_captures; my $package = $self->in_package; my $setup_code = join '', $self->setup_code, # $_[2] being what is passed to _eval_do below Sub::Quote::capture_unroll('$_[2]', $self->lexicals, 2); my $capture_code = join '', $self->capture_code; local our $current_code = qq! ${setup_code} sub Eval::WithLexicals::Cage::current_line { package ${package}; #line 1 "(eval)" ${to_eval} ;sub Eval::WithLexicals::Cage::pad_capture { } ${capture_code} sub Eval::WithLexicals::Cage::grab_captures { no warnings 'closure'; no strict 'vars'; package! # hide from PAUSE .q! Eval::WithLexicals::VarScope;!; # rest is appended by Eval::WithLexicals::Util::capture_list, called # during parsing by the BEGIN block from capture_code. $self->_eval_do(\$current_code, $self->lexicals, $to_eval); $self->_run(\&Eval::WithLexicals::Cage::current_line); } sub _run { my($self, $code) = @_; my @ret; my $ctx = $self->context; if ($ctx eq 'list') { @ret = $code->(); } elsif ($ctx eq 'scalar') { $ret[0] = $code->(); } else { $code->(); } $self->lexicals({ %{$self->lexicals}, %{$self->_grab_captures}, }); @ret; } sub _grab_captures { my ($self) = @_; my $cap = Eval::WithLexicals::Cage::grab_captures(); foreach my $key (keys %$cap) { my ($sigil, $name) = $key =~ /^(.)(.+)$/; my $var_scope_name = $sigil.'Eval::WithLexicals::VarScope::'.$name; if ($cap->{$key} eq eval "\\${var_scope_name}") { delete $cap->{$key}; } } $cap; } sub _eval_do { my ($self, $text_ref, $lexical, $original) = @_; local @INC = (sub { if ($_[1] eq '/eval_do') { open my $fh, '<', $text_ref; $fh; } else { (); } }, @INC); do '/eval_do' or die $@; } { package # hide from PAUSE Eval::WithLexicals::Util; use B qw(svref_2object); sub capture_list { my $pad_capture = \&Eval::WithLexicals::Cage::pad_capture; my @names = grep defined && length > 1, map $_->PV, grep $_->can('PV'), svref_2object($pad_capture)->OUTSIDE->PADLIST->ARRAYelt(0)->ARRAY; $Eval::WithLexicals::current_code .= '+{ '.join(', ', map "'$_' => \\$_", @names).' };' ."\n}\n}\n1;\n"; } } 1; __END__ =head1 NAME Eval::WithLexicals - pure perl eval with persistent lexical variables =head1 SYNOPSIS # file: bin/tinyrepl #!/usr/bin/env perl use strictures 1; use Eval::WithLexicals; use Term::ReadLine; use Data::Dumper; use Getopt::Long; GetOptions( "plugin=s" => \my @plugins ); $SIG{INT} = sub { warn "SIGINT\n" }; { package Data::Dumper; no strict 'vars'; $Terse = $Indent = $Useqq = $Deparse = $Sortkeys = 1; $Quotekeys = 0; } my $eval = @plugins ? Eval::WithLexicals->with_plugins(@plugins)->new : Eval::WithLexicals->new; my $read = Term::ReadLine->new('Perl REPL'); while (1) { my $line = $read->readline('re.pl$ '); exit unless defined $line; my @ret; eval { local $SIG{INT} = sub { die "Caught SIGINT" }; @ret = $eval->eval($line); 1; } or @ret = ("Error!", $@); print Dumper @ret; } # shell session: $ perl -Ilib bin/tinyrepl re.pl$ my $x = 0; 0 re.pl$ ++$x; 1 re.pl$ $x + 3; 4 re.pl$ ^D $ =head1 METHODS =head2 new my $eval = Eval::WithLexicals->new( lexicals => { '$x' => \1 }, # default {} in_package => 'PackageToEvalIn', # default Eval::WithLexicals::Scratchpad context => 'scalar', # default 'list' prelude => 'use warnings', # default 'use strictures 1' ); =head2 eval my @return_value = $eval->eval($code_to_eval); =head2 lexicals my $current_lexicals = $eval->lexicals; $eval->lexicals(\%new_lexicals); =head2 in_package my $current_package = $eval->in_package; $eval->in_package($new_package); =head2 context my $current_context = $eval->context; $eval->context($new_context); # 'list', 'scalar' or 'void' =head2 prelude Code to run before evaling code. Loads L by default. my $current_prelude = $eval->prelude; $eval->prelude(q{use warnings}); # only warnings, not strict. =head2 with_plugins my $eval = Eval::WithLexicals->with_plugins("HintPersistence")->new; Construct a class with the given plugins. Plugins are roles located under a package name like C. Current plugins are: =over 4 =item * HintPersistence When enabled this will persist pragams and other compile hints between evals (for example the L and L flags in effect). See L for further details. =back =head1 AUTHOR Matt S. Trout =head1 CONTRIBUTORS David Leadbeater haarg - Graham Knop (cpan:HAARG) =head1 COPYRIGHT Copyright (c) 2010 the Eval::WithLexicals L and L as listed above. =head1 LICENSE This library is free software and may be distributed under the same terms as perl itself. =cut ))))entry(namex86_64-linux-thread-multinode(type directoryentry(nameautonode(type directoryentry(nameEvalnode(type directoryentry(name WithLexicalsnode(type directoryentry(name .packlistnode(typeregularcontents/gnu/store/00n86di6yhhrbcrvpiv1ag0099sk4pcn-perl-eval-withlexicals-1.003006/bin/tinyrepl /gnu/store/00n86di6yhhrbcrvpiv1ag0099sk4pcn-perl-eval-withlexicals-1.003006/lib/perl5/site_perl/5.36.0/Eval/WithLexicals.pm /gnu/store/00n86di6yhhrbcrvpiv1ag0099sk4pcn-perl-eval-withlexicals-1.003006/lib/perl5/site_perl/5.36.0/Eval/WithLexicals/WithHintPersistence.pm /gnu/store/00n86di6yhhrbcrvpiv1ag0099sk4pcn-perl-eval-withlexicals-1.003006/share/man/man1/tinyrepl.1 /gnu/store/00n86di6yhhrbcrvpiv1ag0099sk4pcn-perl-eval-withlexicals-1.003006/share/man/man3/Eval::WithLexicals.3 /gnu/store/00n86di6yhhrbcrvpiv1ag0099sk4pcn-perl-eval-withlexicals-1.003006/share/man/man3/Eval::WithLexicals::WithHintPersistence.3 ))))))))))))))))))entry(namesharenode(type directoryentry(namemannode(type directoryentry(nameman1node(type directoryentry(nametinyrepl.1.zstnode(typeregularcontents(/d E,:Cp ,N]r LT.R$ ѕuxW0u fn܉)h1&T mr[:kr\ sP_p_ 7;6fǀ{},R;-Mh=yg {^ IFl/ :P 8˪Ŋ񈇋"Rl~qC˓9H PM=9c&E8+~%5jKh\u+TB4f< ٍ$eYxƆA!EH.1X2e8EU&9-nogוּIvg铮N*4:uunpoH0@RڙO,FGT&* 55ȄĠJM=2m c  ו!|X(49$lX>!R \ ƫURvvٍm+%˸0HmHq/|BxOh+,@Ixk#aWFHΌvw+.\fx.6(‚u"hĮiIB[@뗎P{uIp>>)_Mow62C_䆵 ŮV}\[mwS%hyp2ZWT<J*%nj@ONG!qɅ'Hݔ !ʼMGC2AW|< 8 }{xrwRֲO̫^ϟD GLW*G8Ĵ{0}H7ݫw.ݟG(4f9`|s,'}S~7;bWNXJ1=;'(GG<+]5O Tڪ6lJ/٘:)E" I"Dұ*UHSӾ'Y'2 B?[flĜb9ّlܶ5P/jWd^qBAP%RY9 j*9Z99yҕUcpTIB@-mKY|fA81tuȶ:T,j^5`bk%剘*K]ω O4*52>:LLj*  .4+x$(*E X _ X@yG8N=@0>6">#^%7I,JeEmu)Ѯדp|k^S%e]D]Ż$J˪͓ń8<ׇk?lӌ_ !Gq.&SkrɛwBb.b7\*# 7F٩U˾:]"6lU!YVtCDvup];.2R[MNxu 3"}جn'+5גC} \STqep%zFPC$ppIȣ7]zL$)U q<\A9FIO4j"@HiY{]/Cn64/z)Z)MFB肐lV.^i#p9Vx_.CY` Jn}Ih[@nB))entry(name-Eval::WithLexicals::WithHintPersistence.3.zstnode(typeregularcontents(/d M.E -s@W ?T`>,@&xH-S?Q3 f&B,-Z.v?3{gwRy'}}A q GT9uв}3 ͮ{,N;_Mx=ye{e zBl¦9 Y-R!">L0:c㆖'w^FQm-c}?/O~cRF$O,HmG,\wgFt2jg|t1aG agQҌ-kʹxع+44Xn :n7nLJ1W0Y~GVw,*r}K'z]Tb:YV@W\#@Hp׼s3؁d"awi+$ 'it%`VUW̷p8 4,B>aogL4Mv]]rلejs^}Z^4L "`aV3uKAp$;;Su(.KPT4l$LZsh0ʌ r)F3MGrWѺ0&D5NQ ]*̄)~Ҿl4M8˸e˺ NBLHOG!;"Mʂ2Ԥ@ui~uAqH.1-Tь Icq1ZI \4d#" RRPj3@-`i&aƴi'`8"tn ]e"񘐺,Nv[ 瘔W L1[hzW$G/o(JA֫!B2xvO  LPa^1k~>M{ĕiS$F]Tࣴ[m&@S _А#Zn I TXQw{羦_uuDDǻaw#zqe0R# �n8,#,l2\!Q߶UseFl !6q^O6QAdlH*i?*XWEj8eUMkV8_Tm?RD~~p_,RdĂ3:UØOQIM;><|$;'U1جn|Yņ%+8~WTF_6ّ%$3wX#\xIՇcވX8X*6?tDK4ҵnN?yU:ϒg]ƈ岔q8 a-dNG< J8zN x2dٻ'b>DZx= a PQ=ZYOO)))))))))