#!/usr/bin/env perl
our
(
$mydir
,
$myname
);
BEGIN {
my
$location
= (-l $0) ? abs_path($0) : $0;
$location
=~ /(.*?)([^\/]+?)_?\z/s or
die
"?"
;
(
$mydir
,
$myname
) = ($1, $2);
}
sub
usage {
print
"
$myname
[ calculation(s) ]
Repl-Enhanced PerL
Evaluates the
given
string(s), or goes into interactive mode
if
none
given
.
Interactive mode tricks:
- uses
readline
(
read
up on its features)
- entering nothing re-evaluates the
last
entry
-
'strict vars'
is not active, so there's
no
need to declare new
- global variables and subroutines stay
around
, lexical (
'my'
)
varibles don't
- you can refer to
'\$VAR1'
etc. to get the correspondin result from the
previous evaluation (as long as you
're using the default '
:d'
display mode)
- enter
':?'
to get a list of special commands and mode switches
Options:
-t trap exceptions in a repl, too
-H|--
no
-history
do
not save history to file (it is still
read
on
startup.)
--name name
use
name instead of the name of this script as part
of the history file name: ~/.\${name}_history
-M module
use
the
given
module (namespace or path)
-m module same as -M but don't complain about failures
";
exit
@_
;
}
my
@files
;
my
$opt_H
;
my
@opt_M
;
my
@opt_m
;
my
$opt_t
;
for
(
my
$i
= 0;
$i
<=
$#ARGV
;
$i
++) {
local
$_
=
$ARGV
[
$i
];
if
(/^--?h(elp)?$/) {
usage
}
elsif
(
$_
eq
'--'
) {
push
@files
,
@ARGV
[
$i
+ 1 ..
$#ARGV
];
last
;
}
elsif
(
$_
eq
'-H'
or
$_
eq
'--no-history'
) {
$opt_H
= 1;
}
elsif
(
$_
eq
'-t'
) {
$opt_t
= 1;
}
elsif
(/^-M(.*)/) {
if
($1) {
push
@opt_M
, $1;
}
else
{
my
$arg
=
$ARGV
[++
$i
];
defined
$arg
or usage
"missing argument to -M"
;
push
@opt_M
,
$arg
;
}
}
elsif
(/^-m(.*)/) {
if
($1) {
push
@opt_m
, $1;
}
else
{
my
$arg
=
$ARGV
[++
$i
];
defined
$arg
or usage
"missing argument to -m"
;
push
@opt_m
,
$arg
;
}
}
elsif
(/^--name$/) {
my
$arg
=
$ARGV
[++
$i
];
defined
$arg
or usage
"missing argument to --name"
;
$myname
=
$arg
;
}
elsif
(/^-/) {
warn
"Unknown option '$_'\n"
;
usage(1)
}
else
{
push
@files
,
$_
}
}
my
$HISTFILE
= xsafehome .
"/.${myname}_history"
;
warn
$@
if
$@;
push_withrepl(0)
if
$opt_t
;
sub
moduleoption_to_code {
@_
== 1 or fp_croak_arity 1;
my
(
$a
) =
@_
;
$a
=~ s/([^=]+)//s or
die
"invalid -M option '$_'"
;
my
$path_or_package
= $1;
my
$p
= package_of_path_or_package(
$path_or_package
);
"use "
.
do
{
if
(
$a
=~ s/^=//s) {
$p
.
" "
.
join
(
", "
,
map
{
"'$_'"
}
split
/,/,
$a
)
}
else
{
$p
}
}
}
if
(
@opt_M
) {
my
$code
=
join
(
";"
,
map
{ moduleoption_to_code
$_
}
@opt_M
);
&WithRepl_eval
(
"package $myname; "
.
$code
.
"; 1"
) or
die
$@;
}
for
my
$path_or_package
(
@opt_m
) {
eval
moduleoption_to_code
$path_or_package
;
}
if
(
@files
) {
for
(
@files
) {
my
(
$res
,
$e
,
$is_error
) =
&WithRepl_eval_e
(
$_
,
$myname
);
die
$e
if
$is_error
;
print
"$res\n"
;
}
}
else
{
FP::Repl::repl(
maybe_historypath
=> (
$opt_H
?
undef
:
$HISTFILE
),
maybe_package
=>
$myname
);
}