NAME

MM::Table - Pure-Perl mimic of APR::Table (multi-valued, case-insensitive table)

SYNOPSIS

use MM::Table ();
use MM::Const qw( :table );

my $t = MM::Table->make;

$t->set( Foo => "one" ) || die( $t->error );
$t->add( foo => "two" ) || die( $t->error );

my $v  = $t->get( 'FOO' );     # "one" (scalar ctx: oldest)
my @vs = $t->get( 'foo' );     # ("one","two")

$t->merge( foo => "three" );   # first "foo" becomes "one, three"

my $copy = $t->copy;

my $o = $t->overlay( $copy );

$t->compress( OVERLAP_TABLES_SET );    # flattens to last value per key
$t->compress( OVERLAP_TABLES_MERGE );  # flattens to "a, b, c"

$t->do( sub{ print "$_[0] => $_[1]\n"; 1 } ) || die( $t->error );

# APR-like deref:
$t->{foo} = "bar";      # calls set()
print $t->{foo};        # calls get()
print "yes\n" if( exists( $t->{foo} ) );

while( my( $k, $v ) = each( %$t ) )
{
    print "$k => $v\n";    # duplicates preserved in insertion order
}

VERSION

v0.5.0

DESCRIPTION

A pure-Perl, ordered, multi-valued, case-insensitive key-value table, modelled on APR::Table. Used internally by Mail::Make::Headers to store mail header fields in insertion order while allowing case-insensitive lookup and multiple values per field name.

ERROR HANDLING

MM::Table does not inherit from Module::Generic, but follows the same error convention used throughout the Mail::Make ecosystem:

  • On error, a method stores a Mail::Make::Exception object via "error" and returns undef in scalar context or an empty list in list context.

  • The caller retrieves the exception with $t->error.

  • "pass_error" is provided for propagating an error set earlier in the same object.

Because MM::Table is never instantiated by untrusted input and construction cannot fail, there is no class-level MM::Table->error — errors are always per-instance.

CONSTRUCTOR

make

my $t = MM::Table->make;

Creates and returns a new, empty MM::Table instance.

METHODS

add( $key, $value )

Appends a new entry without removing any existing entries for $key. Returns $self, or undef on error.

clear

Removes all entries. Returns $self.

compress( $flags )

Flattens duplicate keys. $flags must be OVERLAP_TABLES_SET (0) to keep only the last value, or OVERLAP_TABLES_MERGE (1) to join all values with ", ". Returns $self, or undef on error.

copy

Returns a deep copy of the table as a new MM::Table instance.

do( $callback [, @filter_keys] )

Iterates over all entries in insertion order, calling $callback-( $key, $value )> for each. Iteration stops if the callback returns a false value. If @filter_keys is provided, only entries whose lowercased key matches one of the filter keys are visited. Returns $self, or undef on error.

error( [$message] )

Without argument: returns the stored Mail::Make::Exception object, or undef if no error has occurred.

With one or more arguments: joins them into a message, creates a Mail::Make::Exception, stores it, and returns undef.

get( $key )

In scalar context: returns the value of the first matching entry, or undef. In list context: returns all values for $key, in insertion order. Returns undef/empty list on error.

merge( $key, $value )

If an entry for $key already exists, appends ", $value" to its value. Otherwise behaves like "add". Returns $self, or undef on error.

overlap( $other_table, $flags )

Copies all entries from $other_table into $self. With OVERLAP_TABLES_SET each key is replaced; with OVERLAP_TABLES_MERGE values are appended. Returns $self, or undef on error.

overlay( $other_table )

Returns a new MM::Table containing all entries from $other_table followed by all entries from $self ($other_table entries come first). Returns the new table, or undef on error.

pass_error

Propagates the error currently stored in this instance by returning undef. If called with arguments, delegates to "error" to create a new exception first.

set( $key, $value )

Removes all existing entries for $key and adds a single new one. Returns $self, or undef on error.

unset( $key )

Removes all entries for $key. Returns $self, or undef on error.

TIED-HASH INTERFACE

MM::Table overloads %{} to expose a tied hash interface compatible with APR::Table's $t->{key} syntax. Assignment calls "set", deletion calls "unset", and each/keys/values iterate in insertion order. Multiple values for the same key are all visited during iteration.

NOTES / LIMITATIONS

  • Performance

    All lookups are linear scans. MM::Table is designed for the small, bounded sets of headers found in email messages, not for large tables.

  • copy and the $pool argument

    The copy method accepts no arguments. The $pool parameter present in the original APR::Table API has no equivalent here.

AUTHOR

Jacques Deguest <jack@deguest.jp>

SEE ALSO

APR::Table, Mail::Make::Headers, Mail::Make::Exception

COPYRIGHT & LICENSE

Copyright(c) 2026 DEGUEST Pte. Ltd.

All rights reserved.

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