Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

Intermixed perl?

by bschmer (Friar)
on Nov 09, 2007 at 14:21 UTC ( [id://649904]=perlquestion: print w/replies, xml ) Need Help??

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

At my place of employment, we have a several "command interpreters" that take a files such as
command1 param1=value1 param2=value2 command2 param3=value3 param4=value4
or even
parallel { command1 param1=value1 param2=value2 command2 param3=value3 param4=value4 }
there are some other constructs in the "language" but those are the basics. The problem is that I'd like to be able to intersperse Perl amongst the commands such that I can have "scripts" such as
command1 param1=value1 param2=value2 <?perl if ($last_command_status == FAIL){ ?> debugging_command debug_param1=debug_value1 <?perl } ?> command2 param1=value1 param2=value2
without changing the format of files that don't have embedded Perl code.

The more complex of the interpreter uses Parse::RecDescent but I'd like to avoid pulling all of the Perl syntax into the interpreter. I've also poked around with Filter::Simple to wrap the non-perl lines by calls to subroutines to handle things but it doesn't "feel" right.

How would you handle this situation?

Replies are listed 'Best First'.
Re: Intermixed perl?
by Corion (Patriarch) on Nov 09, 2007 at 14:33 UTC

    Turn the problem around. If you look at it as having Perl around command interpreter snippets, the problem becomes different:

    #!/usr/bin/perl -w use strict; use vars qw($last_status); sub run_external { my $cmd = shift; print "Running [$cmd]"; $last_status = system($cmd); $last_sys_error = $?; return $last_status }; run_external(<<COMMAND); command1 param1=value1 param2=value2 COMMAND for my $machine (@machines) { run_external(<<COMMAND); command1 machine=$machine param1=value1 param2=value2 COMMAND if ($last_status) { run_external(<<COMMAND); debugging_command machine=$machine debug_param1=debug_va +lue1 COMMAND }; };

    Of course, this requires you to start all your new/complex files with Perl and your simple files with the other interpreter/the shell. I would write a wrapper that checks (say) the file extension or whatnot to launch the correct interpreter for the program.

Re: Intermixed perl?
by suaveant (Parson) on Nov 09, 2007 at 14:36 UTC
    Sounds like you want a pre-processor.... something that runs through the file parsing bits and returns a command file for your interpreter. Which works as long as all the data you need is available ahead of time.

    That way you don't have to change any of your parsers.

                    - Ant
                    - Some of my best work - (1 2 3)

Re: Intermixed perl?
by jbert (Priest) on Nov 09, 2007 at 16:37 UTC
    I think Text::Template does exactly this.

    You can embed perl code in your templates, escaped in the way you choose.

      I'm gathering that bschmer is feeding the commands to that interpreter, and the perl code should be able to make decisions on the RESULTS of those individual commands. (See the == FAIL case he illustrates.) Thus, the behavior or selection of later commands can be adjusted based on the results in earlier tests. Correct me if I'm wrong, but pre-authoring a more complicated script file ahead of time with a simple template tool won't help there.

      [ e d @ h a l l e y . c c ]
      This is my 1000th posting to PerlMonks.

        No, you're right. But I don't see how the problem as posed makes sense since he wants to add syntactic constructs (e.g. close brace }) at runtime (i.e. post-parse).

        So I'd guess I'd solve his specific problem by adding some plugin capability to his interpreters, so I could do something like MYEMPLOYER_APP_PLUGINS=Foo,Bar and then the Foo and Bar plugins get called at various stages of command and argument processing.

        This would require defining an API for the plugins in terms of what they could inspect and what they could change.

        So this is work. And hence sucks, and this is why little languages (DSLs) suck unless they are embedded within a more powerful general purpose language (so you can escape to the big language when you need to). Otherwise you find yourself re-inventing loops, conditionals, I/O etc in your little language over time.

        So I guess really I'd write a converter to make all of these cmd files become perl and then just embed perl. It could be fairly mechanical (he already has the parsers):

        command1({param1 => "value1", param2 => "value2"});
        and then pre-load a per-interpreter module which provides functions (command1 etc) which must also already exist.
Re: Intermixed perl?
by Porculus (Hermit) on Nov 09, 2007 at 18:15 UTC
    Do you need the full power of Perl for your "scripts"? If all you want to do is add simple conditional execution like in your example, the simplest approach might be to extend the interpreter to provide the features you have use-cases for.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://649904]
Approved by marto
Front-paged by suaveant
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (4)
As of 2024-05-24 13:12 GMT
Find Nodes?
    Voting Booth?

    No recent polls found