http://qs321.pair.com?node_id=514574

dimar has asked for the wisdom of the Perl Monks concerning the following question:

OVERVIEW:
I have an application where I am attempting to use a simple mechanism for inclusion (hereinafter 'inheritance' (used in a non-OOP, non technical sense)) of 'text blurbs' based on perl modules. The problem is how to persist the notion of 'inheritance' even after the perl code has been run or 'auto-generated'. The details are as follows. A code sample is below.

PROBLEM1:
How do you obviate the need to reproduce text blurbs in multiple places, when what you *really* want to do is inherit those text blurbs from a single, centralized source.

SOLUTION1:
Naive Inheritance solves Problem1. Simply define a MainModule that serves as a repository for all centralized text blurbs. Then include them from that MainModule whenever and wherever necessary.

PROBLEM2:
Naive Inheritance does not work with this particular application, because sometimes the perl source is 'auto-generated' and 'auto-republished'. This means that, from time to time, an identity transformation is applied to (for example) CustomerModule.pm, and the entire module code is 'refreshed' via automated process. This 'refresh' operation causes the inherited text blurbs to be 'flattened' into their plain text equivalents. This breaks the intended benefits of using inheritance.

QUESTION1:
What is a solution to fix Problem2 (the problem of Naive Inheritance) in which the variable values are replaced with their plain-text equivalent?
In order to illustrate the question, a simple example follows (portions omitted for space):

### begin: package CustomerModule ### ... ### ... ### begin node: ccPastDue30 %hDataRec = ( caption => 'Past Due 30 Days', domain => 'customer_corresp', codename => 'ccPastDue30', desc => 'for accounts that are 30 days late', keywords => 'customer warning deadbeat', ### ----------------------------------------------- body => q^ ^.MainModule::StandardHeader().q^ Dear __fname__ __lname__, It has come to our attention that your account is 30 days past due. Please address this oversight as soon as possible to avoid late fees and additional charges. Thank you. ^.MainModule::StandardFooter().q^ ^, ### ----------------------------------------------- ); do{my %hTemp = %hDataRec; $root->{$hTemp{mnemonic}} = \%hTemp; };### end_node ### begin node: ccPastDue60 ### ... ### ... };### end_node ### begin node: ccPastDue90 ### ... ### ... };### end_node
When the above code is run in 'output' context, we obviously want the 'StandardHeader' and 'StandardFooter' portions replaced with their plain-text equivalent. However, when the code is run in 'republish' or 'auto-generate perl' contexts, we do not want the StandardHeader or StandardFooter portions to be interpolated at all.
=oQDlNWYsBHI5JXZ2VGIulGIlJXYgQkUPxEIlhGdgY2bgMXZ5VGIlhGV

Replies are listed 'Best First'.
Re: modules, auto generated code and content management
by philcrow (Priest) on Dec 06, 2005 at 19:57 UTC

      The goal is to reduce dependencies on templating systems. They are nice, but they don't do anything perl can't do alone. Moreover, Perl, Mason and TT all have easy solutions to Problem1, but that still does not address Problem2.

      There needs to be a way to output the content of the 'body' variable without having the 'inherited' portions interpolated. I was hoping for insight on how to address this issue, or at least workarounds from others who have encountered this specific issue before, assuming there are others.

      As far as I can discern, the only solution (be it TT, Mason, or whatever else) would be to convert the module code into some 'intermediate' format (XML, YAML, some other 'markup') and then 'scrape' the content out that way, thus avoiding interpolation of interspersed variables in the text

      =oQDlNWYsBHI5JXZ2VGIulGIlJXYgQkUPxEIlhGdgY2bgMXZ5VGIlhGV

        You're absolutely right - templating systems don't do anything that perl can't do without them. Well, not quite. Templating systems usually can offer a much more simplified view of the data. Content, with no logic. That's what templating is for.

        How I generally approach this problem is to put my content in templates, and put the retrieval of data in the code. In your case, I would use the "include" facilities of most templating systems to put the common header and footer into header and footer templates:

        <tmpl_include header.tmpl> Dear <tmpl_var fname> <tmpl_var lname>, It has come to our computer's attention that your account is 30 days past due. You don't really want our computer mad at you - last time it was mad at me, it conveniently lost half my email and mangled the crap out of my automated scripts. With you, I predict adding some zeros somewhere in the middle of your account balance. Please pay up before the computer sends a hitman to your house. Thanks, HAL <tmpl_include footer.tmpl>

        I'm really not sure what you mean by "republish" or "auto-generate perl" modes. Something tells me that you're looking for extra work with those.

Re: modules, auto generated code and content management
by santonegro (Scribe) on Dec 06, 2005 at 23:45 UTC
    Perhaps your phrases can be stored in a relational database. Otherwise, take a look at the copious phrasebook modules on CPAN, like Class::Phrasebook. Also, is it not possible to regenerate the data of the module without re-generating the module itself? Why are you creating and re-generating modules?
Re: modules, auto generated code and content management
by dimar (Curate) on Dec 07, 2005 at 02:04 UTC

    Thanks, monks for the replies so far, especially Tanktalus and santonegro. Since the crux of my question is primarily contingent upon the nature of 'republishing' and 'auto-generation' (non-standard terms) here is a quick update to further illustrate what is going on. To make it as straightforward as possible, I will do a quick sketch of what the application is all about. Skip ahead to the Summary for the quick punch line.

    Summary:
    Considering the requirements (esp. 'Body Armoring' and 'Node Referencing') the choice was to use perl modules as the syntax to store the text nodes. The pm files work well, but the 'republishing' problem still persists (i.e., how can we regenerate the code in the pm files such that all the text nodes appear in alphabetical order, and the body content does not get interpolated and expanded). I had already considered other options, so the following comparison table may also give some useful info.

    So far, only pm files have all 'yes' values, with the obvious exception that motivated me to post this question.

    FeatureNumber:      1   2   3   4   5   6   7
    Perl Modules        y   y   !   y   y   y   y
    TemplateToolkit     y   y   ?   y   y   n   y
    Class::Phrasebook   y   y   ?   ?   n   ?   n
    YAML                y   y   y   n   n   y   y
    XML                 y   y   y   n   n   n   n
    


    The search for wisdom continues ...
    =oQDlNWYsBHI5JXZ2VGIulGIlJXYgQkUPxEIlhGdgY2bgMXZ5VGIlhGV