NAME

MPGA - Make Perl Great Again - a module for Flow-Driven Development in Perl

SYNOPSIS

use MPGA;

# --- Basic flow without shared context ---

sub fun : MPGAargsNum(2) {
    my ($self, $args, $flow, $ctx) = @_;
    my ($a, $b) = @$args;
    print "Got arguments: $a and $b\n";
    return;
}

flow( [ "transit_arg", 5, 6, \&fun ] );

# --- Using flow_ctx with a shared context ---

sub step_one : MPGAargsNum(2) {
    my ($self, $args, $flow, $ctx) = @_;
    $ctx->{sum_result} = $args->[0] + $args->[1];
    return;
}

sub step_two : MPGAargsNum(0) {
    my ($self, $args, $flow, $ctx) = @_;
    print "Sum from previous step: $ctx->{sum_result}\n";
    return;
}

my $my_context = { sum_result => 0 };
flow_ctx( [ $my_context, 10, 20, \&step_one, \&step_two ] );

DESCRIPTION

A "flow" is simply an array reference containing a mix of data (arguments) and code references (functions). These elements are sequentially processed from left to right.

The Function Signature

Each function in the flow must expect four arguments:

sub fun1 : MPGAargsNum(2) {
    my ($self, $args, $flow, $ctx) = @_;
    
    # $self - reference to this function itself
    # $args - array ref of arguments passed to this function
    # $flow - array ref of the remaining flow (can be modified)
    # $ctx  - optional context object shared across the flow
    
    return;
}

The :MPGAargsNum(N) Attribute

The :MPGAargsNum(N) attribute explicitly defines how many arguments your function consumes from the flow. MPGA will automatically extract the N arguments immediately preceding the function.

Any arguments in the flow that appeared before those N arguments are considered transit arguments. They are safely preserved and automatically pushed back into the flow to be consumed by subsequent functions.

(Note: Older code without this attribute receives all preceding arguments and must manage them manually. This backward compatibility is fully preserved).

Return Values

Functions can return values to inject new data or functions into the beginning of the remaining flow:

  • Array reference [...]: Elements are unpacked and prepended to the flow.

  • Hash reference {...} or Scalar: Prepended to the flow as a single element.

  • undef (or empty return;): The flow remains unchanged.

Shared Context

If you need to share state across multiple functions, use flow_ctx(). The first element of the array is treated as a shared context object and is passed to all functions as the 4th argument.

Execution Limits

To protect against infinite loops, flow() accepts a step limit as the 3rd argument (0 = unlimited):

flow($flow_array, $ctx, 100); # Stops after 100 steps

SEE ALSO

MPGA::Trace - For real-time execution monitoring.

https://github.com/nni7/MPGA

AUTHOR

Nikolay Neustroev (NN)

COPYRIGHT AND LICENSE

Copyright (C) 1997-2026 by Nikolay Neustroev.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.