AnyEve...llback(3pm)

πŸ“¦
version 0.06 Β· 2 versions
, in debian bookworm, debian trixie, ubuntu jammy, ubuntu noble

πŸ’– AnyEve...llback β€” a.k.a. AnyEvent::Callback πŸ’–

okay bestie, sit down, hydrate, because this is the callback aggregator for AnyEvent watchers and it is genuinely iconic. it's a 3pm page, so yes, it's Perl, and yes, it's from the User Contributed Perl Documentation shelf. we're doing this. 🫢


✨ NAME ✨

AnyEvent::Callback β€” callback aggregator for AnyEvent watchers. that's the whole vibe. it takes your messy little pile of callbacks and makes it make sense. πŸ’…


🌸 SYNOPSIS 🌸

first, the way you'd usually look at watchers, all chaotic and unstructured:

    use AnyEvent::Callback;

    # usually watchers are looked as:
    AE::something @args, sub { ... };
    AE::something
        @args,
        sub { ... },    # result
        sub { ... };    # error

and now the glow-up, with CB:

    use AnyEvent::Callback;

    AE::something @args, CB { ... };
    AE::something @args,
        CB sub { ... },     # result
            sub { ... };    # error

    AE::something @args,
        CB sub { ... },     # result
            sub { ... },    # error
            sub { ... };    # anyway callback

so the order is result, then error, then the anyway callback. three slots, no confusion, we love a structured queen. πŸ‘‘

πŸ¦‹ Callback hierarchy πŸ¦‹

you can spawn child callbacks that are bound to their parent:

    my $cbchild = $cb->CB(sub { ... });

    ...

    $cbchild->error('error'); # will call $cb->error('error');

the way that an error just *travels up the family tree*… generational. 🌈

πŸŽ€ Inside Your callback You can: πŸŽ€

    sub my_watcher {
        my $cb = pop;
        my @args = @_;

        # ...

        $cb->error( @error );   # error callback will be called
        # or:
        $cb->( $value );        # result callback will be called
    }

two moves: throw an error, or drop a result. pick one, bestie. πŸ™ˆ

πŸ’œ Callbacks stack πŸ’œ

    my $cbs = CBS;

    for (1 .. $n) {
        AE::something @args, $cbs->cb;
    }

    $cbs->wait(sub {
        for (@_) {
            if ($_->is_error) {     # handle one error
                my @err = $_->errors; # or:
                my $errstr = $_->errstr;
            } else {                # results
                my @res = $_->results;
            }
        }

    });

CBS collects them all, $cbs->wait waits for the whole squad, and then you loop through the outcomes like a main character reviewing her receipts. ✨


πŸ’€ DESCRIPTION πŸ’€

so what does this module actually do? three things, and they're all lowkey genius:

  • it lets you create a callback hierarchy.
  • it groups error and result callbacks into one object. one object. that's it. that's the whole trick. πŸŽ€
  • it checks whether a callback was ever called by the watcher or not. and here's the spicy part β€” if a watcher doesn't call the result or error callback, the error callback gets called automatically. no silent failures in this house. 😭
also, it checks if a callback was called reentrant. if it was, the module will complain β€” and it complains using carp in Carp. so you will hear about it.

and one more: if a watcher touches the error callback, and the superior didn't define an error callback, the module will call the error callback upwards through the hierarchy. like passing a note up to the front of the class. example:

    AE::something @args, CB \&my_watcher, \&on_error;

    sub on_error {

    }

    sub my_watcher {
        my $cb = pop;

        ...

        the_other_watcher $cb->CB( sub { # error callback wasn't defined
            my $cb = pop;
            ...
            yet_another_watcher1 $cb->CB( sub {
                my $cb = pop;
                ...
                $cb->( 123 );   # upwards callback

            });
            yet_another_watcher2 $cb->CB( sub {
                my $cb = pop;
                ...

                $cb->error( 456 );  # on_error will be called

            });
        });
    }

see how yet_another_watcher1 calls $cb->( 123 ) and that result floats up, while yet_another_watcher2 calls $cb->error( 456 ) and on_error gets summoned? that's the hierarchy doing its thing. fr fr. πŸ”₯


🌟 METHODS 🌟

πŸ‘‘ 'CODE' (overloaded fake method) πŸ‘‘

    $cb->( ... );

You can use the object as usually CODEREF. yes, it just works as a coderef. iconic behavior.

🌸 CB 🌸

Creates new callback object that have binding on parent callback.

    my $new_cb = $cb->CB(sub { ... });   # the cb doesn't catch errors

    my $new_cb = CB(sub { ... }, sub { ... }); # the cb catches errors

    my $new_cb = $cb->CB(sub { ... }, sub { ... }); # the same

so: one sub β†’ no error catching. two subs β†’ error catching. and calling it off $cb versus calling CB bare with two subs? the same. πŸ’…

πŸ¦‹ error πŸ¦‹

Calls error callback. If the object has no registered error callbacks, parent object's error callback will be called.

    $cb->error('WTF?');

and honestly? 'WTF?' is a whole mood. valid string. 😭


    Copyright (C) 2012 by Dmitry E. Oboukhov

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. so go off, remix it, slay responsibly. 🫢


and that's the whole page, bestie. no notes. this is AnyEve...llback, section 3pm, part of the User Contributed Perl Documentation, and it was last touched on 2021-01-09 running under perl v5.32.0. periodt. πŸ’…βœ¨πŸŒˆ

πŸ“¦ where this page comes from