Peta::Shell::Session#
evaluate Perl line by line and keep the state
SYNOPSIS#
use Peta::Shell::Session;
my $session = Peta::Shell::Session->new;
my $r = $session->eval('my @list = (1, 2, 3); scalar @list');
print "$r->{status}: @{ $r->{values} }\n"; # ok: 3
$r = $session->eval('push @list, 4; "@list"'); # @list is still there
print "@{ $r->{values} }\n"; # 1 2 3 4
$r = $session->eval('for my $i (@list) {');
print $r->{status}, "\n"; # incomplete
DESCRIPTION#
A session evaluates pieces of Perl one after another as if they were consecutive lines of one program. What a line leaves behind is there for every later line:
its
my,stateandourvariables, when declared at the line’s top level;its pragmas:
use strict,use warnings,use feature,use v5.36and any other lexical pragma;the current package;
subs, packages and loaded modules, as in any program.
A variable declared inside a block of the line (for my $i (...), if (...) { my $t }) belongs to that block and is gone with it, as in a program.
Each line is compiled once and run at once. A line that does not compile changes nothing. A line that dies keeps what it had declared and assigned before it died.
How a my variable survives#
The variable itself is kept, not a copy: after the line that declares it, later lines reach it under its name as a package variable of a hidden package, bound with our when the line is compiled. So a closure and a named sub see every later assignment, \$x is the same reference in every line, and a second my $x in a later line makes a new variable while subs compiled before keep the old one.
Two things follow from “package variable”. local $x works on it in a later line, which a true lexical refuses. And the name is resolved when a line is compiled, so text compiled later at run time (a string eval) sees the variable, but a symbolic reference by its plain name does not.
METHODS#
new#
my $session = Peta::Shell::Session->new(%options);
Options:
name
The name lines are reported under. Line 12 of a session named
ippsis the file(ipps:12)in messages. Defaultipps.package
The package the first line is compiled in. Default
main.preamble
Perl evaluated before the first line; it sets the pragmas the session starts with and is not counted as a line. Default
use strict qw(refs subs); use warnings;. Pass an empty string for none.
Dies if the preamble does not compile or dies.
eval#
my $result = $session->eval($text);
Passes $text through the preprocessors, compiles it and runs it in list context. $text may hold several lines. Returns a hash reference:
status
ok,error,incompleteorempty.incompletemeans the text ends inside a construct: an open bracket, a string or here-document without its end, an expression that expects more. Nothing was run. The caller reads more input and callsevalagain with the whole text.emptymeans there was nothing but blank space, before or after the preprocessors.values
Array reference: what the last statement returned, in list context. Empty unless the status is
ok.error
For
error: the exception, as it was thrown (a string or an object).phase
For
error:preprocess,compileorrun.warnings
Array reference of the warnings the line raised, compiling or running, unless a line has installed its own
$SIG{__WARN__}, which then gets them.line
The line number this text got. Only
okanderrortexts are numbered.text
The text after the preprocessors.
wall, cpu
Seconds of wall-clock and of processor time, compiling and running.
variables#
my @names = $session->variables;
The names of the session’s variables with their sigils, sorted.
variable#
my $ref = $session->variable('@list');
A reference to the variable itself, or undef when the session has none of that name.
bind#
$session->bind('$ans', \$value);
Makes the referenced variable the session’s variable of that name, as if a line had declared it. The name is a sigil ($, @ or %) and an identifier; the reference must be of the matching kind.
package#
The package the next line is compiled in.
line#
The number of the last numbered line; 0 before the first.
name#
The session’s name.
add_preprocessor#
$session->add_preprocessor(sub { my ($text, $session) = @_; ...; $text });
Appends a preprocessor. Before a text is compiled it passes through the preprocessors in the order they were added; each gets the text and the session and returns the text to go on with. Returning an empty string ends the line there (status empty). An exception makes the line an error of phase preprocess.
This is where macros, aliases and commands of the shell live: they turn what was typed into Perl.
remove_preprocessor#
$session->remove_preprocessor($code);
Removes that preprocessor. Returns true if it was there.
preprocessors#
The list of preprocessors, in order.
LIMITS#
Text that turns out to be incomplete has still been compiled as far as it went, so a
useorBEGINblock in it has already run and runs again when the completed text is compiled.localat a line’s top level lasts to the end of that line.The match variables (
$1,$&) are scoped to the line.A lexical sub (
my sub name) is not kept.