Though I don't understand how tie() works, too, I know how to use it ;)
The following class represents a hash whose keys are
case-insensitive:
package Insensitive::Hash;
use strict;
use warnings;
sub new {
my ( $class, @args ) = @_;
my %self;
while ( my ($key, $value) = splice @args, 0, 2 ) {
$self{ lc $key } = $value;
}
bless \%self, $class;
}
sub get {
my ( $self, $key ) = @_;
$self->{ lc $key };
}
sub set {
my ( $self, $key, $value ) = @_;
$self->{ lc $key } = $value;
}
1;
How can we use Insensitive::Hash?
use strict;
use warnings;
use Insensitive::Hash;
my $hash = Insensitive::Hash->new(
'Content-Type' => 'text/plain',
);
# $key is case-insensitive
$hash->get( 'Content-Type' ); # => "text/plain"
$hash->get( 'content-type' ); # => "text/plain"
$hash->set( 'CONTENT-TYPE' => 'text/html' );
To implement tie() interface, rename the method names of Insensitive::Hash as follows:
package Insensitive::Hash;
use strict;
use warnings;
# new -> TIEHASH
# get -> FETCH
# set -> STORE
sub TIEHASH {
my ( $class, @args ) = @_;
my %self;
while ( my ($key, $value) = splice @args, 0, 2 ) {
$self{ lc $key } = $value;
}
bless \%self, $class;
}
sub FETCH {
my ( $self, $key ) = @_;
$self->{ lc $key };
}
sub STORE {
my ( $self, $key, $value ) = @_;
$self->{ lc $key } = $value;
}
1;
How tie() works?
use strict;
use warnings;
use Insensitive::Hash;
tie my %hash, 'Insensitive::Hash', ( 'Content-Type' => 'text/plain' );
# <=> my $hash = Insensitive::Hash->TIEHASH( ... )
$hash{'Content-Type'}; # <=> $hash->FETCH( 'Content-Type' );
$hash{'content-type'}; # <=> $hash->FETCH( 'content-type' );
$hash{'CONTENT-TYPE'} = 'text/html';
# <=> $hash->STORE( 'CONTENT-TYPE' => 'text/html' );
Insensitive::Hash was taken from "Object-oriented Perl" written by D. Conway.
See also HTTP::Headers (field names are case-insensitive).