[LA.pm] What to call a small module

Ben Tilly btilly at gmail.com
Mon Apr 30 21:21:59 PDT 2012


On Mon, Apr 30, 2012 at 8:54 PM, Uri Guttman <uri at stemsystems.com> wrote:
> On 04/30/2012 09:47 PM, Ben Tilly wrote:
>>
>> I have a small module, I just don't know what to call it.  Does anyone
>> have any suggestions?
>>
>> It just takes a hash, and expands it as a template, with the variables
>> referring to other keys.  It can even handle nested hashes.  So you
>> might pass it something like this:
>>
>>   {
>>     user =>  'btilly',
>>     project_root =>  '/home/[% user %]/foo',
>>     template_root =>  '[% project_root %]/app/view',
>>     escaped =>  '\[% watch_this %]',
>>   }
>>
>> and then get back:
>>
>>   {
>>     user =>  'btilly',
>>     project_root =>  '/home/btilly/foo',
>>     template_root =>  '/home/btilly/foo//app/view',
>>     escaped =>  '[% watch_this %]',
>>   }
>>
>> The use case is mostly for configuration files, where you'd have a
>> hash describing a basic sandbox template, override the values you need
>> to, and then get the configuration for a developer.  With this sort of
>> templating, the amount that you need to override goes way down.
>
>
> couple of ideas:
>
> Template::HashValues
> Template::Config
>
> but why another template module? template::simple can do that with a simple
> values loop (untested):
>
>        # add template paths or files here
>        my $tmpl = Template::Simple->new() ;
>        # $conf has the replacement values as a hash ref
>        $_ = ${$tmpl->render( $_, $conf )} for values %config_hash ;

Your simple loop does not handle recursive replacement.  In  my simple
example above, the user btilly got inserted into the project root and
then that into the template root.  If you just expanded everything
over and over again until nothing looked like a template, that would
kind of work.  But what if you wanted to wind up with a piece of TT
syntax, there is no way to do that.  (I support an escape mechanism
for that.)

But it gets worse.  The original use case for this code has to handle
nested hashes as well.  Let me illustrate.  In a base config:

  $PARAM{prod} = {
    email_qa_email => undef,
    email_pager_email => 'some_pagers at appropriate_companies',
    # etc
    email => {
      qa_email => '[% email_qa_email %]',
      pager_email => '[% email_pager_email %]',
      # etc
    },
  };

And then:

  $PARAM{sandbox} = {
    %{$PARAM{prod}},
    default_email => '[% user %]@company.com',
    email_qa_email => 'QA <[% default_email %]>',
    email_pager_email => 'Pagers <[% default_email %]>',
    # etc.
  };

And then:

  $PARAM{some_user} => {
     %{$PARAM{sandbox}},
    user => 'some_user',
  };

At this point $PARAM{some_user} contains:

  {
    user => 'some_user',
    default_email => '[% user %]@company.com',
    email_qa_email => 'QA <[% default_email %]>',
    email_pager_email => 'Pagers <[% default_email %]>',
    # etc
    email => {
      qa_email => '[% email_qa_email %]',
      pager_email => '[% email_pager_email %]',
      # etc
    },
  }

And after expansion will contain:

  {
    user => 'some_user',
    default_email => 'some_user at company.com',
    email_qa_email => 'QA <some_user at company.com>',
    email_pager_email => 'Pagers <some_user at company.com>',
    # etc
    email => {
      qa_email => 'QA <some_user at company.com>',
      pager_email => 'Pagers <some_user at company.com>',
      # etc
    },
  }

Note that the nested hash now contains the results of substitutions
that have been expanded recursively 3 times.

I looked for a wheel that looked like it would fit.  I did not find
one.  So I coded a new one.  (Currently 120 lines long.  But I still
need to add documentation, etc.)


More information about the Losangeles-pm mailing list