# phpman > perldoc > POE::Filter::Stackable

## NAME
    [POE::Filter::Stackable](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3AStackable/markdown) - combine multiple [POE::Filter](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter/markdown) objects

## SYNOPSIS
      #!perl

      use POE qw(
        [Wheel::FollowTail](https://www.chedong.com/phpMan.php/perldoc/Wheel%3A%3AFollowTail/markdown)
        [Filter::Line](https://www.chedong.com/phpMan.php/perldoc/Filter%3A%3ALine/markdown) [Filter::Grep](https://www.chedong.com/phpMan.php/perldoc/Filter%3A%3AGrep/markdown) [Filter::Stackable](https://www.chedong.com/phpMan.php/perldoc/Filter%3A%3AStackable/markdown)
      );

      [POE::Session](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3ASession/markdown)->create(
        inline_states => {
          _start => sub {
            my $parse_input_as_lines = [POE::Filter::Line](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3ALine/markdown)->new();

            my $select_sudo_log_lines = [POE::Filter::Grep](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3AGrep/markdown)->new(
              Put => sub { 1 },
              Get => sub {
                my $input = shift;
                return $input =~ /sudo\[\d+\]/i;
              },
            );

            my $filter_stack = [POE::Filter::Stackable](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3AStackable/markdown)->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](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AWheel%3A%3AFollowTail/markdown)->new(
              Filename => "/var/log/system.log",
              InputEvent => "got_log_line",
              Filter => $filter_stack,
            );
          },
          got_log_line => sub {
            print "Log: $_[ARG0]\n";
          }
        }
      );

      [POE::Kernel](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AKernel/markdown)->run();
      exit;

## DESCRIPTION
    [POE::Filter::Stackable](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3AStackable/markdown) combines multiple filters together in such a way that they appear to be a
    single filter. All the usual [POE::Filter](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter/markdown) methods work, but data is secretly passed through the
    stacked filters before it is returned. [POE::Wheel](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AWheel/markdown) objects and stand-alone programs need no
    modifications to work with a filter stack.

    In the "SYNOPSIS", [POE::Filter::Line](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3ALine/markdown) and [POE::Filter::Grep](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3AGrep/markdown) are combined into one filter that
    only returns a particular kind of line. This can be more efficient than filtering lines in
    application space, as fewer events may need to be dispatched and handled.

    Internally, filters are stored in an array.

    Data added by get_one_start() will flow through the filter array in increasing index order.
    Filter #0 will have first crack at it, followed by filter #1 and so. The get_one() call will
    return an item after it has passed through the last filter.

### put
    with the highest index first, and put() will return the results after data has passed through
    filter #0.

## PUBLIC FILTER METHODS
    In addition to the usual [POE::Filter](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter/markdown) methods, [POE::Filter::Stackable](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3AStackable/markdown) also supports the
    following.

  new
    By default, new() creates an empty filter stack that behaves like [POE::Filter::Stream](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3AStream/markdown). It may be
    given optional parameters to initialize the stack with an array of filters.

      my $sudo_lines = [POE::Filter::Stackable](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3AStackable/markdown)->new(
        Filters => [
          [POE::Filter::Line](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3ALine/markdown)->new(),
          [POE::Filter::Grep](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3AGrep/markdown)->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. Any data remaining in the filter's input buffer is lost, but an
    application may always call "get_pending" in [POE::Filter](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter/markdown) on the returned filter.

      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 the filter's input buffer is 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](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter/markdown) 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
    process input last, and they will handle output first.

      # Reverse data read through the stack.
      # rot13 encode data sent through the stack.
      $stackable->push(
        [POE::Filter::Map](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3AMap/markdown)->(
          Get => sub { return scalar reverse shift() },
          Put => sub { local $_ = shift(); tr[a-zA-Z][n-za-mN-ZA-M]; $_ },
        )
      );

  unshift FILTER[, FILTER]
### unshift
    FILTERs will process input first, and they will handle output last.

  filters
### filters
    order.

    Calling "$filter_stack->filters()" in the "SYNOPSIS" would return a list of two filter objects:

      [POE::Filter::Line](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3ALine/markdown)=[ARRAY(0x8b5ee0)](https://www.chedong.com/phpMan.php/man/ARRAY/0x8b5ee0/markdown)
      [POE::Filter::Grep](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3AGrep/markdown)=[ARRAY(0x8b5f7c)](https://www.chedong.com/phpMan.php/man/ARRAY/0x8b5f7c/markdown)

  filter_types
### filter_types
    order.

    Calling "$filter_stack->filter_types()" in the "SYNOPSIS" would return a list of two class
    names:

      [POE::FIlter::Line](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFIlter%3A%3ALine/markdown)
      [POE::Filter::Grep](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3AGrep/markdown)

    It could easily be replaced by:

      my @filter_types = map { ref } $filter_stack->filters;

## SEE ALSO
    [POE::Filter](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter/markdown) for more information about filters in general.

    Specific filters, amongst which are: [POE::Filter::Block](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3ABlock/markdown), [POE::Filter::Grep](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3AGrep/markdown), [POE::Filter::HTTPD](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3AHTTPD/markdown),
    [POE::Filter::Line](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3ALine/markdown), [POE::Filter::Map](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3AMap/markdown), [POE::Filter::RecordBlock](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3ARecordBlock/markdown), [POE::Filter::Reference](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3AReference/markdown),
    [POE::Filter::Stream](https://www.chedong.com/phpMan.php/perldoc/POE%3A%3AFilter%3A%3AStream/markdown)

## BUGS
    None currently known.

AUTHORS & COPYRIGHTS
    The Stackable filter was contributed by Dieter Pearcey. Documentation provided by Rocco Caputo.

    Please see the POE manpage for more information about authors and contributors.

