CPS::Governor(3pm)

πŸ“¦
version 0.19 Β· 7 versions
, in debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking

✨ NAME ✨

CPS::Governor β€” bestie, this is the thing that controls how the CPS functions iterate πŸ’… (it's a User Contributed Perl Documentation page, and yes it lives at CPS::Governor(3pm), we're fancy like that)


πŸ’– DESCRIPTION πŸ’–

Okay so listen. Objects built on this abstract class get handed to the gk* variants of the CPS functions, and their whole job is controlling how those functions behave. The vibe is: these objects are expected to provide a method called again, and the functions will call it to re-invoke iterations of loops and stuff like that.

And the iconic part? Because you're writing again yourself, governor objects can give you all kinds of behaviours β€” rate-limiting, asynchronisation, parallelism, or even integration with event-based IO frameworks. It's giving ✨main character energy✨ for your control flow.


πŸŽ€ CONSTRUCTOR πŸŽ€

$gov = CPS::Governor->new

You must call this on a subclass that actually implements the again method β€” no shortcuts, bestie, this class is abstract fr fr. It hands you back a brand new instance of a governor object in that class. 🫢


πŸ¦‹ SUBCLASS METHODS πŸ¦‹

Because this is an abstract class, you literally cannot construct instances of it directly β€” only on a subclass that implements the following methods. No cap. πŸ™ˆ

$gov->again( $code, @args )

Run the function that's chilling in the CODE reference $code, passing in the arguments @args.

Now here's the tea β˜• β€” if you're going to execute that immediately, it should be invoked using a tail-call directly by the again method, so that the stack does not grow arbitrarily. Yes, arbitrarily. Don't do that to your stack, she's been through enough.

You can pull that off like this:

@_ = @args;
goto &$code;

Alternatively, Sub::Call::Tail can be used to apply some syntactic sugar, which lets you write this instead:

use Sub::Call::Tail;
...
tail $code->( @args );

Look at that. Gorgeous. πŸ˜­πŸ‘‘


🌈 EXAMPLES 🌈

A Governor With A Time Delay 🌸

Consider the following subclass β€” it implements a CPS::Governor subclass that calls sleep() between every single invocation. Every. Single. One. πŸ’€

package Governor::Sleep

use base qw( CPS::Governor );

sub new
{
   my $class = shift;
   my ( $delay ) = @_;

   my $self = $class->SUPER::new;
   $self->{delay} = $delay;

   return $self;
}

sub again
{
   my $self = shift;
   my $code = shift;

   sleep $self->{delay};

   # @args are still in @_
   goto &$code;
}
Note the little comment in there: @args are still in @_ β€” that's the whole trick, bestie, that's why the goto &$code works so cleanly. 🧚

⭐ SEE ALSO ⭐

  • Sub::Call::Tail β€” Tail calls for subroutines and methods

πŸ‘‘ AUTHOR πŸ‘‘

Paul Evans <leonerd@leonerd.org.uk> β€” the icon, the legend πŸ’œ


And that's a wrap, bestie! This page came to you courtesy of perl v5.34.0, dated 2022-06-30, and it's CPS::Governor(3pm) β€” go forth and govern your iterations, you absolute legend. Slay. πŸŽ€βœ¨

πŸ“¦ where this page comes from