use external files as "HERE-docs" (and avoid the undefined substitions)

Discussion in 'Perl Misc' started by dede, Dec 15, 2004.

  1. dede

    dede Guest

    Hello friends of the community,

    find below the solution I am currently using to load external
    text-files that
    are seamlessly interpolated to behave like the useful HERE-docs:

    echo <<"EOT";
    Hello $strWorld ...
    EOT

    SNIPPET:

    while (<$handle>) {
    $_ =~ s/(\$\S+)/defined eval($1) ? eval($1) : $1/gsxe;
    #interpolate all $vars or $self->vars etc.
    #note that this "old test"...
    #$_ =~ s/(\$\w+)/defined $1 ? $1 : "undefined"/gsxee;
    #produced the notorious "undefined substitution errors"

    #here might be some extra cleanup-work of the file

    push @lines, $_;
    } #each line;
    close $handle;

    A.
    Note that you can substitute ANY var or OO-pseudo hash-var (ie.
    inst-var)
    from the namespace of the context (function/method) that this snippet
    resides in.
    B.
    You might also be more specific and include some static text in the
    search
    pattern and then add some .. eval('whatever'.$1.'foo') .. stuff.
    C.
    Note that the defined eval (...) is necessary in order to return values
    that
    Perls likes to interpret as FALSE (eg. '' or 0).

    Any comments / immprovements are welcome.
    Share and Enjoy :)

    dede, Paris / France
    dede, Dec 15, 2004
    #1
    1. Advertising

  2. dede

    Paul Lalli Guest

    "dede" <> wrote in message
    news:...

    > $_ =~ s/(\$\S+)/defined eval($1) ? eval($1) : $1/gsxe;


    my $str = 'line';
    $_ = 'What about ${str}s like this?';

    Paul Lalli
    Paul Lalli, Dec 15, 2004
    #2
    1. Advertising

  3. dede <> wrote:

    > find below the solution I am currently using to load external
    > text-files that
    > are seamlessly interpolated to behave like the useful HERE-docs:



    What is wrong with making the external files be Real Perl Code,
    and then simply require()ing them?


    > $_ =~ s/(\$\S+)/defined eval($1) ? eval($1) : $1/gsxe;



    The s///s modifier affects only dot, it is a no-op when the
    pattern does not contain a dot. You should not add modifiers
    willy nilly, add them only when you _need_ them.

    The s///x modifier allows whitespace and comments in the pattern,
    it is a no-op when there is no whitespace nor comments in
    the pattern (more willy-nillyness).

    Where are these mysterious "text files" coming from?

    Consider what your code will do with file contents like:

    $foo;unlink(<*>)

    for instance.


    > #$_ =~ s/(\$\w+)/defined $1 ? $1 : "undefined"/gsxee;
    > #produced the notorious "undefined substitution errors"



    It is not "notorious", it is "fictional". :)

    What message is it that you are really referring to?

    Does the message appear in perldiag.pod? I can't find it...


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Dec 16, 2004
    #3
  4. dede

    dede Guest

    Thanks for your remark, Paul

    actually, yes , i assumed that there is always a whitespace delimiting
    the end of the string, since I wanted to be as close to the "normal"
    way of identifying variables as possible.
    We might change to ..... s/(\${.+})/ defined eval ...... to force the
    curly brackets as "tidy" syntax in the external file (that i use to
    build HTMLs - see other reply).
    This would protect us against "accidents" like wrong evals of
    $something and enhance (slightly) the performance due to the not-made
    eval's.
    what do you think?

    dede
    dede, Dec 16, 2004
    #4
  5. dede

    dede Guest

    Salut Tad,
    thank you 4 your helpful remarks.

    a) Require ?
    Uh, i was not clear on this one. I actually "scan" the external files
    like SQL-scripts or HTML-templates to get these "dynamic" - a bit like
    using JSP-variables or PHP-vars. Soon I'd like to publish a
    Pod-HTML-site generator that uses this technique.

    b) Unnecessary modifiers !
    Yeah - you are right. A nasty side effect of doing copy&paste, or
    "willy-nilly" programming as you might put it. Acknowledged.

    c) Errors?
    Hmmm ... again .. 1st think then post - shame on me.
    The error is actually called
    "Use of uninitialized value in substitution iterator at
    config/Scanner.pm line 501" (freshly generated today with Perl 5.8.4.
    Activestate)

    Merci again,
    dede
    dede, Dec 16, 2004
    #5
  6. dede wrote:

    > Hello friends of the community,
    >
    > find below the solution I am currently using to load external
    > text-files that
    > are seamlessly interpolated to behave like the useful HERE-docs:
    >
    > echo <<"EOT";
    > Hello $strWorld ...
    > EOT
    >
    > SNIPPET:
    >
    > while (<$handle>) {
    > $_ =~ s/(\$\S+)/defined eval($1) ? eval($1) : $1/gsxe;


    This is unduely messy and complicated.

    By using \S+ you expose yourself to all the dangers of eval().

    By not using a single eval() of a here-doc you make the syntax of the
    files unnecessarily un-Perl like.

    If you have already accepted all the costs of using eval() you may as
    well get all the beniefit.

    my $text = do { local $/; <$handle> };
    chop ( $text = eval "<<__END__\n$text\n__END__" );

    This, of course, assumes that you can reasonably slurp the whole file.

    Although as Tad points out it may be better simply to make the files
    real Perl files and do() or require() them.

    I should add that you may even want to make the template be the actual
    Perl scripts and make them use your module.

    > Note that the defined eval (...) is necessary in order to return values
    > that Perls likes to interpret as FALSE (eg. '' or 0).


    Why not simply switch off the warning?

    > Any comments / immprovements are welcome.


    You are inventing yet another templating system.

    Perl already has two built-in templating systems (here-docs and formats)
    and others on CPAN. You should think hard before you invent another.
    Brian McCauley, Dec 16, 2004
    #6
  7. "dede" <> wrote in news:1103195035.162812.281040
    @z14g2000cwz.googlegroups.com:

    > c) Errors?


    Dunno. Please quote the part of the post you are replying to and place
    your replies below the original text. That way, people other than you can
    figure out what you are replying to.

    > Hmmm ... again .. 1st think then post - shame on me.


    Exactly.

    > The error is actually called
    > "Use of uninitialized value in substitution iterator at


    That is a warning.

    Try

    use diagnostics;

    to get more information.

    --
    A. Sinan Unur
    d
    (remove '.invalid' and reverse each component for email address)
    A. Sinan Unur, Dec 21, 2004
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alexander Malkis
    Replies:
    8
    Views:
    516
    Alexander Malkis
    Apr 14, 2004
  2. Rafal Zawadzki
    Replies:
    1
    Views:
    390
    Stefan Behnel
    Jul 16, 2006
  3. Roger23
    Replies:
    2
    Views:
    994
    Roger23
    Oct 12, 2006
  4. James Edward Gray II

    Feature Request: Truly Indented Here-Docs

    James Edward Gray II, Oct 3, 2004, in forum: Ruby
    Replies:
    10
    Views:
    216
    Brian Candler
    Oct 4, 2004
  5. MST
    Replies:
    7
    Views:
    146
    Vetle Roeim
    Jul 12, 2004
Loading...

Share This Page