sub CONSUME_LINE
() { 1; }
sub CONSUME_WORDS
() { 2; } # currently unsupported
sub CONSUME_TOKENS
() { 3; }
#####################################################################
#####################################################################
$name=ucfirst(lc($name));
unless (exists $loaded{$name}) {
my $tmp='Psh::Strategy::'.$name;
$obj= "Psh::Strategy::$name"->new();
@order= grep { $name ne $_->name } @order;
delete $active{$name} if $active{$name};
my $tmpdir= Psh
::OS
::catdir
($tmp,'Psh','Strategy');
my @tmp= Psh
::OS
::glob('*.pm',$tmpdir);
foreach my $strat (@tmp) {
return sort keys %result;
for (my $i=0; $i<@order; $i++) {
if ($order[$i]->name() eq $strategy) {
my $suggested_pos= shift;
my $max= $#order; # add right before eval
my @tmp= $str_obj->runs_before();
$max= $tmp if $tmp<$max and $tmp>=0;
my $consumes= $str_obj->consumes();
for (my $i=0; $i<=$max; $i++) {
if ($order[$i]->consumes()<$consumes) {
if ($order[$i]->consumes()>$consumes) {
if (defined $suggested_pos) {
if ($pos>=$min and $pos<=$max) {
splice(@order,$pos,0,$str_obj);
$active{$str_obj->name}=1;
@lvl1order= grep { $_ && $_->consumes() == CONSUME_LINE
} @order;
@lvl2order= grep { $_ && $_->consumes() == CONSUME_WORDS
} @order;
@lvl3order= grep { $_ && $_->consumes() == CONSUME_TOKENS
} @order;
sub parser_strategy_list
{
return (\
@lvl1order,\
@lvl2order,\
@lvl3order);
sub parser_return_objects
{
my @objs= map { get
($_) } @_;
my @lvl1= grep { $_->consumes() == CONSUME_LINE
} @objs;
my @lvl2= grep { $_->consumes() == CONSUME_WORDS
} @objs;
my @lvl3= grep { $_->consumes() == CONSUME_TOKENS
} @objs;
return (\
@lvl1,\
@lvl2,\
@lvl3);
require Psh
::StrategyBunch
;
foreach my $name (qw(bang perl brace built_in perlfunc executable eval)) {
my $tmpname= ucfirst($name);
$obj= "Psh::Strategy::$tmpname"->new();
splice(@order,@order-1,0, get
('darwin_apps'));
#####################################################################
# Base class for strategies
#####################################################################
my $class= ref($proto) || $proto;
if ($class=~/^Psh::Strategy::(.*)$/) {
return $loaded{$name} if exists $loaded{$name};
die 'Strategies must be in Psh::Strategy:: namespace!';
Psh::Strategy - a Perl Shell Evaluation Strategy (base class)
Psh::Strategy offers a procedural strategy list interface and a
base class for developing strategies.
=head1 PROCEDURAL STRATEGY LIST
Returns a list of active Psh::Strategy objects.
my $obj= Psh::Strategy::get('name')
Loads and initializes a certain Psh::Strategy object
Psh::Strategy::add($obj [, $suggest_position])
Adds a strategy object to the list of active strategies
Psh::Strategy::remove($name)
@list= Psh::Strategy::available_list()
Lists available strategies
Finds the position of the named strategy
Returns true if the named strategy is currently active
=head1 DEVELOPING STRATEGIES
You have to inherit from Psh::Strategy and you MUST at least
override the functions C<consumes>, C<applies>, C<execute>.
You CAN also override the function C<runs_before>
Returns either CONSUME_LINE, CONSUME_WORDS, CONSUME_TOKENS.
CONSUME_LINE means you want to receive the whole input line
unparsed. CONSUME_WORDS means you want to receive the whole
input line tokenized (currenty unimplemented). CONSUME_TOKENS
means that you want to receive a sub-part of the line, tokenized
(this is probably what you want)
Returns undef if the strategy does not want to handle the input.
Returns a human-readable description if it wants to handle the input.
If you specified CONSUME_LINE, this method will be called as
$obj->applies(\$inputline);
If you specified CONSUME_TOKENS, this method will be called as
$obj->applies(\$inputline,\@tokens,$piped_flag)
$obj->execute(\$inputline,\@tokens,$how,$piped_flag)
C<$how> is what the call to applies returned. If C<@tokens> is
not applicable an empty array will be supplied.
Your execute function should return an array of the form:
($evalcode, \@words, $forcefork, @return_val)
If C<$evalcode>, <@words> and <$forcefork> are undef, execution is finished
after this call and C<@return_val> will be used as return value.
But C<$evalcode> can also be a Perl sub - in which case it is evaluated
later on, or a string - in which case it's a filename of a program to
execute. C<@words> will then be used as arguments for the program.
C<$forcefork> may be used to force a C<fork()> call even for the perl
Returns a list of names of other strategies. It is guaranteed that
the evaluation strategy will be tried before those other named strategies