View on
MetaCPAN is shutting down
For details read Perl NOC. After June 25th this page will redirect to
Ben Tilly > Template-ExpandHash > Template::ExpandHash



Annotate this POD

View/Report Bugs
Module Version: 0.01   Source  


Template::ExpandHash - Do template expansion on the values of a hash.


Version 0.01


    use Template::ExpandHash qw(expand_hash);
    # ... time passes
    %expanded_hash    = expand_hash(%hash);
    $expanded_hashref = expand_hash($hashref);

Pass a hash, get back a similar hash with [% key %] expanded into the value associated with that key. Recursive substitutions are supported, and the substituting goes into sub-hashes. (Sub-hashes can expand to keys from the surrounding hash, but not vice versa.) Template expressions can be escaped using backslashes.


When loading a configuration it often makes sense to start with a base configuration data structure, and then load multiple layers of tweaks for specific environments. This can happen within pure Perl as in this example:

    $PARAM{prod} = {
        email_qa_email      => undef,
        email_pager_email   => '',
        some_escaped_value  => '\[% user ]%',
        # etc
        email => {
          qa_email          => '[% email_qa_email %]',
          pager_email       => '[% email_pager_email %]',
          # etc
        # More data here.

    $PARAM{sandbox} = {
        default_email       => '[% user %]',
        email_qa_email      => 'QA <[% default_email %]>',
        email_pager_email   => 'Pagers <[% default_email %]>',
        # More data here, some of which overrides prod.

    $PARAM{btilly} = {
        user                => 'btilly',
        # More data here, some of which overrides the sandbox.

Alternately it can happen in a series of files which you might load from a list of external sources with code like this:

    use Config::Any;

    # ... code here.
    my $raw_config_list
        = Config::Any->load_files({files => \@config_path, use_ext => 1});
    my $config = {map %$_, map values %$_, @$raw_config_list};

Either way there is a tendency for the set of overrides at the detail level to get very long. However with templating we could make this much shorter. Suppose that our final set of parameters worked out to be something like:

    $config =  {
        user                => 'btilly',
        default_email       => '[% user %]',
        email_qa_email      => 'QA <[% default_email %]>',
        email_pager_email   => 'Pagers <[% default_email %]>',
        some_escaped_value  => '\[% user ]%',
        # etc
        email => {
          qa_email          => '[% email_qa_email %]',
          pager_email       => '[% email_pager_email %]',
          # etc
        # More data here.

Then we can expand all of the template parameters:

    $expanded_param = expand_hash($param);

And get:

        user               => 'btilly',
        default_email      => '',
        email_qa_email     => 'QA <>',
        email_pager_email  => 'Pagers <>',
        some_escaped_value => '[% user ]%',
        # etc
        email => {
            qa_email       => 'QA <>',
            pager_email    => 'Pagers <>',
            # etc
        # More data here.

without having to manually override a long list of values. This makes your configuration much simpler and cleaner than it otherwise would be.



The only externally usable function. You pass it a hash or hash ref and it will recursively expand template parameters and return you a hash or hash ref.


Ben Tilly, <btilly at>


Error checking

No checks currently exist for malformed templates, or template references to variables that are not available. These would catch common typos and should be added.


Currently it keeps on passing through the list of not yet done variables until no further progress is made. Calculating a dependency graph up front could significantly help performance.


All of the real work is done in one giant recursive function. It could be broken up into more digestable pieces.

Conditionals and loops

Common template features do not work. Perhaps they would be useful.

Recursive macro expansion

[% foo[% bar %] %] does not currently work. It may be simple to add.


Please report any bugs or feature requests to bug-template-expandhash at, or through the web interface at I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.


You can find documentation for this module with the perldoc command.

    perldoc Template::ExpandHash

Or email the author at <btilly at>.

The project home is


This module was produced under contract to They are a good group of people, and I thank them for allowing this to be open sourced.

All mistakes are, of course, mine.


Copyright 2012 Ben Tilly.

Sponsored by

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See for more information.

syntax highlighting: