NAME
Hash::Map - Manipulate hashes map like
VERSION
0.004
SYNOPSIS
Hint
When I write
$obj = $obj->this_method;
I mean, that the Hash::Map object itself will be returned. So it is possible to build chains like that:
$obj->this_method->next_method;
It is typical used for setter or worker methods.
OO style
require Hash::Map;
# Constructor typical not called directly.
# Methods "target", "target_ref", "source", "source_ref"
# and combine are alternative constructors.
my $obj = Hash::Map->new;
# set target hash
$obj = $obj->target(a => 1);
$obj = $obj->target_ref({a => 1});
# get target hash (no set parameters)
$target = $obj->target;
$target = $obj->target_ref;
# set source hash
$obj = $obj->source(b => 2, c => 3);
$obj = $obj->source_ref({b => 2, c => 3});
# get source hash (no set parameters)
$source = $obj->source;
$source = $obj->source_ref;
# combine - merge targets of other Hash::Map objects into $obj target
$obj = $obj->combine(@objects);
# clone target
$obj = $obj->clone_target;
# clone source
$obj = $obj->clone_source;
# delete keys in target
$obj = $obj->delete_keys( qw(x y) );
$obj = $obj->delete_keys_ref([ qw(x y) ]);
# copy data from source to target using keys
$obj = $obj->copy_keys(qw(b c))
$obj = $obj->copy_keys_ref([ qw(b c) ]);
# including a key rewrite rule as code reference
$obj = $obj->copy_keys(
qw(b c),
sub {
my $obj = shift;
my $key = $_;
return "new $key";
},
);
$obj = $obj->copy_keys_ref(
[ qw(b c) ],
sub {
my $obj = shift;
my $key = $_;
return "new $key";
},
);
# copy data from source (key of map) to target (value of map)
$obj = $obj->map_keys(b => 'bb', c => 'cc');
$obj = $obj->map_keys_ref({b => 'bb', c => 'cc'});
# merge the given hash into target hash
$obj = $obj->merge_hash(d => 4, e => 5);
$obj = $obj->merge_hashref({d => 4, e => 5});
# modify target inplace by given code
$obj = $obj->modify(
f => sub {
my $obj = shift;
my $current_value_of_key_f_in_target = $_;
return; # $target{f} will be undef because of scalar context
},
...
);
$obj = $obj->modify_ref({
f => sub {
my $obj = shift;
my $current_value_of_key_f_in_target = $_;
return "new $value";
},
...
});
# copy data from source to target using keys
# and then
# modify target inplace by given code
$obj = $obj->copy_modify(
f => sub {
my $obj = shift;
my $current_value_of_key_f_in_target = $_;
return; # $target{f} will be undef because of scalar context
},
...
);
$obj = $obj->copy_modify_ref({
f => sub {
my $obj = shift;
my $current_value_of_key_f_in_target = $_;
return "new $value";
},
...
});
$obj = $obj->copy_modify_identical(
qw(b c),
sub {
my $obj = shift;
my $current_value_of_each_key_in_target = $_;
return; # $target{key} will be undef because of scalar context
},
);
$obj->copy_modify_identical_ref(
[ qw(b c) ],
sub {
my $obj = shift;
my $current_value_of_each_key_in_target = $_;
return; # $target{key} will be undef because of scalar context
},
);
# copy data from source (key of map) to target (value of map)
# and then
# modify target inplace by given code
$obj = $obj->map_modify(
f => ff => sub {
my $obj = shift;
my $current_value_of_key_f_in_source = $_;
return; # $target{ff} will be undef because of scalar context
},
...
);
$obj = $obj->map_modify_ref([
f => ff => sub {
my $obj = shift;
my $current_value_of_key_f_in_source = $_;
return "new $value";
},
...
]);
$obj = $obj->map_modify_identical(
(
f => ff,
...
),
sub {
my $obj = shift;
my $current_value_of_each_key_in_source = $_;
return; # $target{key} will be undef because of scalar context
},
);
$obj = $obj->map_modify_identical_ref(
{
f => ff,
...
},
sub {
my $obj = shift;
my $current_value_of_each_key_in_source = $_;
return "new $value";
},
);
Functional style
use Hash::Map qw(hash_map hashref_map);
%target_hash = hash_map(
\%source_hash,
# The following references are sorted anyway.
# Running in order like written.
[ qw(key1 key2) ], # copy_keys from source to target hash
[ qw(key3 key4), $code_ref ], # copy_keys, code_ref to rename keys
{
source_key1 => 'target_key', # map_keys from source to target hash
source_key2 => $code_ref, # modify values in target hash
},
);
Similar, only the method name and return value has changed.
$target_hashref = hashref_map(
$source_hashref,
...
);
Automatic construction
Methods "target", "target_ref", "source", "source_ref" and "combine" can work as constructor too.
Hash::Map->new->target(...);
Hash::Map->new->target_ref(...);
Hash::Map->new->source(...);
Hash::Map->new->source_ref(...);
Hash::Map->new->combine(...);
shorter written as:
Hash::Map->target(...);
Hash::Map->target_ref(...);
Hash::Map->source(...);
Hash::Map->source_ref(...);
Hash::Map->combine(...);
DESCRIPTION
For array manipulation we have map, for hashes not really. This was the reason to create this module.
The fuctional interface is wrapped around the OO inferface. Not all can be implemented functional.
Code example
Don't be shocked about the big examples.
If you have nearly 1 type of each mapping. Map it like before. Otherwise the module helps you to prevent: Don't repeat yourself.
Often we read in code something like that:
foo(
street => $form->{street},
city => $form->{city},
country_code => $form->{country_code} eq 'D'
? 'DE'
: $form->{country_code},
zip_code => $form->{zip},
name => "$form->{first_name} $form->{family_name}",
account => $bar->get_account,
mail_name => $mail->{name},
mail_address => $mail->{address},
);
OO interface
Now we can write:
foo(
Hash::Map->combine(
Hash::Map
->source_ref($form)
->copy_keys(
qw(street city)
)
->copy_modify(
country_code => sub {
return $_ eq 'D' ? 'DE' : $_;
},
->map_keys(
zip => zip_code,
)
->merge_hash(
name => "$form->{first_name} $form->{family_name}",
),
Hash::Map
->source_ref($bar)
->copy_keys(
qw(account),
sub {
my $obj = shift;
my $method = "get_$_";
return $obj->source_ref->$method,
},
),
Hash::Map
->source_ref($mail)
->copy_keys(
qw(name address),
sub {
return "mail_$_";
},
),
)->target
);
Functional interface
Now we can write:
foo(
hash_map(
$form,
[ qw(street city country_code) ],
{
country_code => sub {
return $_ eq 'D' ? 'DE'; $_;
},
zip_code => 'zip',
},
),
name => "$form->{first_name} $form->{family_name}",
hash_map(
$bar,
[
qw(account),
sub {
my $obj = shift;
my $method = "get_$key";
return $obj->source_ref->$method;
},
]
),
hash_map(
$mail,
[
qw(name address),
sub {
return "mail_$_";
},
],
),
);
SUBROUTINES/METHODS
method new
A simple constructor without any parameters.
my $obj = Hash::Map->new;
Typical you don't call method new directly.
method target
Set or get the target hash.
Can not set an empty hash, but this is the default. Otherwise use method target_ref.
$obj = $obj->target(%target);
%target = $obj->target;
This method is able to construct the object first.
Hash::Map->target(...);
method target_ref
Set or get the target hash using a hash reference.
$obj = $obj->target_ref($target_hashref);
$target_hashref = $obj->target_ref;
This method is able to construct the object first.
Hash::Map->target_ref(...);
method source
Set or get the source hash.
Can not set an empty hash, but this is the default. Otherwise use method source_ref.
$obj = $obj->source(%source);
%source = $obj->source;
This method is able to construct the object first.
Hash::Map->source(...);
method source_ref
Set or get the source hash using a hash reference.
$obj = $obj->source_ref($source_hashref);
$source_hashref = $obj->source_ref;
This method is able to construct the object first.
Hash::Map->source_ref(...);
method combine
Merge targets of other Hash::Map objects into $obj target.
$obj = $obj->combine(@objects);
This method is able to construct the object first.
Hash::Map->combine(...);
method clone_target
Using Module Clone to clone the target hash.
$obj = $obj->clone_target;
method clone_source
Using Module Clone to clone the source hash.
$obj = $obj->clone_source;
method delete_keys
Delete keys in target hash.
$obj = $obj->delete_keys(@keys);
method delete_keys_ref
Delete keys in target hash.
$obj = $obj->delete_keys_ref($keys_array_ref);
method copy_keys
Copy data from source to target hash using keys.
$obj = $obj->copy_keys(@keys);
And rename all keys during copy.
$obj = $obj->copy_keys(
@keys,
sub {
my $obj = shift;
my $key = $_;
return "new $key";
},
);
The first parameter of the callback subroutine is the object itself. The current key is in $_. Return the new key.
method copy_keys_ref
Copy data from source to target hash using keys.
$obj = $obj->copy_keys_ref($keys_array_ref);
And rename all keys during copy.
$obj = $obj->copy_keys_ref(
$keys_array_ref,
sub {
my $obj = shift;
my $key = $_;
return "new $key";
},
);
The first parameter of the callback subroutine is the object itself. The current key is in $_. Return the new key.
method map_keys
Copy data from source hash (key is key of map) to target hash (key is value of map).
$obj = $obj->map_keys(%map);
method map_keys_ref
Copy data from source hash (key is key of map) to target hash (key is value of map).
$obj = $obj->map_keys_ref($map_hashref);
method merge_hash
Merge the given hash into the target hash.
$obj = $obj->merge_hash(%hash);
method merge_hashref
Merge the given hash into the target hash.
$obj = $obj->merge_hashref($hashref);
method modify
Modify the target hash inplace by given key and code for.
The first parameter of the callback subroutine is the object itself. The old value of the target hash is in $_; Return the new value.
$obj = $obj->modify(
key1 => $code_ref1,
...
);
method modify_ref
Similar to method modify. Only the given parameter is a hash reference and not a hash.
$obj = $obj->modify_ref({
key1 => $code_ref1,
...
});
method copy_modify
This is a combination of copy_keys and modify.
The first parameter of the callback subroutine is the object itself. The old value of the target hash is in $_; Return the new value.
$obj = $obj->copy_modify(
key1 => $code_ref1,
...
);
It is not possible to rename all keys during copy. Use method map_modify instead.
method copy_modify_ref
Similar to method copy_modify. Only the given parameter is a hash reference and not a hash.
$obj = $obj->copy_modify_ref({
key1 => $code_ref1,
...
});
It is not possible to rename all keys during copy. Use method map_modify_ref instead.
method copy_modify_identical
This is another combination of copy_keys and modify. All values are modified using a common code reference.
The 1st parameter of the callback subroutine is the object itself. The 2nd parameter is the key. The old value of the target hash is in $_; Return the new value.
$obj = $obj->copy_modify_identical(
@keys,
$code_ref,
);
It is not possible to rename all keys during copy. Use method map_modify_identical instead.
method copy_modify_identical_ref
Similar to method copy_modify_identical. Only the given parameter is an array reference and not an array.
$obj = $obj->copy_modify_identical_ref(
$keys_array_ref,
$code_ref,
);
It is not possible to rename all keys during copy. Use method map_modify_identical_ref instead.
method map_modify
This is a combination of map_keys and modify.
The first parameter of the callback subroutine is the object itself. The old value of the target hash is in $_; Return the new value.
$obj = $obj->map_modify(
source_key1 => target_key1 => $code_ref1,
...
);
method map_modify_ref
Similar to method map_modify. Only the given parameter is a array reference and not a array.
$obj = $obj->map_modify_ref([
source_key1 => target_key1 => $code_ref1,
...
]);
method map_modify_identical
This is a combination of map_keys and modify.
The 1st parameter of the callback subroutine is the object itself. The 2nd parameter is the source key and the 3rd parameter is the target key. The old value of the target hash is in $_; Return the new value.
$obj = $obj->map_modify_identical(
source_key1 => target_key1,
...
$code_ref,
);
method map_modify_identical_ref
Similar to method map_modify_identical. Only the given parameter is a array reference and not a array.
$obj = $obj->map_modify_identical_ref(
{
source_key1 => target_key1,
...
},
$code_ref,
);
subroutine hash_map
This subroutine is for the fuctional interface only.
%target_hash = hash_map(
\%source_hash,
# The following references are sorted anyway.
# Running in order like written.
[ qw(key1 key2) ], # copy_keys from source to target hash
[ qw(key3 key4), $code_ref ], # copy_keys, code_ref to rename keys
{
source_key1 => 'target_key', # map_keys from source to target hash
source_key2 => $code_ref, # modify values in target hash
},
);
subroutine hashref_map
Similar, only the method name and return value has chenged.
$target_hashref = hashref_map(
$source_hashref,
...
);
DIAGNOSTICS
nothing
CONFIGURATION AND ENVIRONMENT
nothing
DEPENDENCIES
INCOMPATIBILITIES
none
BUGS AND LIMITATIONS
none
SEE ALSO
map
AUTHOR
Steffen Winkler
inspired by: Andreas Specht <ACID@cpan.org>
LICENSE AND COPYRIGHT
Copyright (c) 2012, Steffen Winkler <steffenw at cpan.org>
. All rights reserved.
This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.