POE::F...ckable(3pm)
π POE::Filter::Stackable β bestie edition β¨
okay so we're reading from the User Contributed Perl Documentation, manual section 3pm, and the star of the show is POE::Filter::Stackable π«Ά pull up a chair, get comfy, this one's actually so good.
πΈ NAME πΈ
POE::Filter::Stackable β combine multiple POE::Filter objects π§ no cap, that's literally the whole job.
π SYNOPSIS π
here's the vibe, in code, exactly as it is:
#!perl
use POE qw(
Wheel::FollowTail
Filter::Line Filter::Grep Filter::Stackable
);
POE::Session->create(
inline_states => {
_start => sub {
my $parse_input_as_lines = POE::Filter::Line->new();
my $select_sudo_log_lines = POE::Filter::Grep->new(
Put => sub { 1 },
Get => sub {
my $input = shift;
return $input =~ /sudo\[\d+\]/i;
},
);
my $filter_stack = POE::Filter::Stackable->new(
Filters => [
$parse_input_as_lines, # first on get, last on put
$select_sudo_log_lines, # first on put, last on get
]
);
$_[HEAP]{tailor} = POE::Wheel::FollowTail->new(
Filename => "/var/log/system.log",
InputEvent => "got_log_line",
Filter => $filter_stack,
);
},
got_log_line => sub {
print "Log: $_[ARG0]\n";
}
}
);
POE::Kernel->run();
exit;
β¨ DESCRIPTION β¨
so POE::Filter::Stackable takes a bunch of filters and glues them together so they act like one single filter. it's giving β¨illusion of unityβ¨. all the usual POE::Filter methods still work like normal, but secretly β lowkey behind the scenes β your data gets passed through all the stacked filters before it comes back to you. and the best part? POE::Wheel objects and stand-alone programs need zero modifications to work with a filter stack. they don't even know. iconic behavior honestly π
in the SYNOPSIS up there, POE::Filter::Line and POE::Filter::Grep get combined into one filter that only returns a particular kind of line. and that's highkey more efficient than filtering lines in application space, because fewer events may need to be dispatched and handled. ate. π₯
internally, the filters are stored in an array. very demure, very mindful.
here's the tea on how data actually flows:
- data added by
get_one_start()flows through the filter array in increasing index order. filter #0 gets first crack at it, then filter #1, and so on down the line. - the
get_one()call returns an item after it has passed through the last filter. so it's been through the whole gauntlet, bestie. put()goes the other way β it passes data through the filters in descending index order. data goes through the filter with the highest index first, andput()returns the results after the data has passed through filter #0.
π PUBLIC FILTER METHODS π
besides all the usual POE::Filter methods, POE::Filter::Stackable also supports the following. yes queen, there's more π
π¦ new π¦
by default, new() creates an empty filter stack that behaves like POE::Filter::Stream. it may also be given optional parameters to initialize the stack with an array of filters. slay.
my $sudo_lines = POE::Filter::Stackable->new(
Filters => [
POE::Filter::Line->new(),
POE::Filter::Grep->new(
Put => sub { 1 }, # put all items
Get => sub { shift() =~ /sudo\[\d+\]/i },
),
]
);
π pop π
behaves like Perl's built-in pop() for the filter stack. the highest-indexed filter is removed from the stack and returned. π heads up though β any data remaining in that filter's input buffer is lost. but it's fine, it's fine, an application may always call "get_pending" in POE::Filter on the returned filter to go get it back.
my $last_filter = $stackable->pop();
my $last_buffer = $last_filter->get_pending();
π shift π
behaves like Perl's built-in shift() for the filter stack. the 0th filter is removed from the stack and returned. any data remaining in that filter's input buffer gets passed to the new head of the stack β or it is lost if the stack becomes empty π. an application may also call "get_pending" in POE::Filter on the returned filter to examine the filter's input buffer.
my $first_filter = $stackable->shift();
my $first_buffer = $first_filter->get_pending();
π push FILTER[, FILTER] π
push() adds one or more new *FILTER*s to the end of the stack. the newly pushed *FILTER*s will process input last, and they will handle output first. okay so the ordering here is the whole point, don't skip it:
# Reverse data read through the stack.
# rot13 encode data sent through the stack.
$stackable->push(
POE::Filter::Map->(
Get => sub { return scalar reverse shift() },
Put => sub { local $_ = shift(); tr[a-zA-Z][n-za-mN-ZA-M]; $_ },
)
);
π§ unshift FILTER[, FILTER] π§
unshift() adds one or more new *FILTER*s to the beginning of the stack. the newly unshifted *FILTER*s will process input first, and they will handle output last. it's the mirror image of push(), and yes she's serving symmetry π
πΈ filters πΈ
filters() returns a list of the filters inside the Stackable filter, in the stack's native order.
calling "$filter_stack->filters()" in the SYNOPSIS would return a list of two filter objects:
POE::Filter::Line=ARRAY(0x8b5ee0)
POE::Filter::Grep=ARRAY(0x8b5f7c)
β filter_types β
filter_types() returns a list of class names for each filter in the stack, in the stack's native order.
calling "$filter_stack->filter_types()" in the SYNOPSIS would return a list of two class names:
POE::FIlter::Line
POE::Filter::Grep
it could easily be replaced by:
my @filter_types = map { ref } $filter_stack->filters;
π₯ SEE ALSO π₯
- POE::Filter for more information about filters in general. the lore, if you will.
- specific filters, amongst which are:
POE::Filter::Block,POE::Filter::Grep,POE::Filter::HTTPD,POE::Filter::Line,POE::Filter::Map,POE::Filter::RecordBlock,POE::Filter::Reference,POE::Filter::Stream
π BUGS π
none currently known. we're flawless, your honor. π
π AUTHORS & COPYRIGHTS π
the Stackable filter was contributed by Dieter Pearcey. documentation provided by Rocco Caputo. thank you legends π«Ά
please see the POE manpage for more information about authors and contributors.
okay that's the whole page bestie, you're officially stacked and slaying π this was perl v5.34.0, dated 2022-03-25, and it's the POE::F...ckable(3pm) page β go forth and stack responsibly β¨ππ¦
π¦ where this page comes from
- debian bookworm: libpoe-perl 2:1.3700-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- debian trixie: libpoe-perl 2:1.3700-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu noble: libpoe-perl 2:1.3700-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu questing: libpoe-perl 2:1.3700-1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms