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

Dear Monks,

My little template programming excersize is getting a more compact solution.

Now I should find a way to substitute a simple function call by using a predefined perl program block. like #define foo(bar)... in C language does. Substitution seems to be mandatory because the block needs to see all local variables.

The block I should simplify is this.

$_ = $input; template::generate(state $compiled //= eval(template::translate()) || +die $@); $output = $_;

The statement I would like to use instead is this.

template::use($input, $output);

Unfortinately the eval() needs to exist in the calling source. It can not be moved to the class method.

Replies are listed 'Best First'.
Re: How to simulate a preprocessor macro without one?
by rcaputo (Chaplain) on Feb 08, 2010 at 02:02 UTC

    Does FIlter-Template approximate what you want? It's a Perl source filter that implements a simple form of code templates. Based on the SYNOPSIS:

    use Filter::Template; template max (one,two) { ((one) > (two) ? (one) : (two)) } # Expand the "max" template inline. # Generates and runs code that prints # the largest value of two scalars. print {% max $a, $b %}, "\n";

Re: How to simulate a preprocessor macro without one?
by LanX (Saint) on Feb 08, 2010 at 03:28 UTC
    Perl5 has (unfortunately) no macro system.

    You may wanna check this list of alternatives Re: Perl keyword like the C/C++ keyword 'inline'

    Additionally in theory it should be possible to intercept the compilation before execution and replace the opcodes of special function calls with other code using B::Concise (and using another module to generate opcode where I can't remember the name right now¹)

    Plz let me know when you implemented it 8)

    Cheers Rolf

    ¹ it's simply B::Generate

      I have studied this issue a little more. I found that practically I do not need an ordinary (source manipulating) macro function at this case. In my case I need an access to the lexical scope of the callers environment to eval string type closures as they would exist inside the callers code.

      Is there any practical method to change the lexical scope temporarily? caller() will give you some access to the callers properties but I think I need more.

      sub foo { my $name="FOO"; bar("$name"); } sub bar { my $name="BAR"; print "My name is $name"; #My name is BAR function_to_do_something_using_callers_lexical_view { print "Your name is $name"; #Your name is FOO } } foo();

      If there is no such function, as I fear, would it be "easy" or even possible to make a plugin which could install this kind of new core function to the interpreter? Or should I make my own Perl release ;-)

        > In my case I need an access to the lexical scope of the callers environment to eval string type closures as they would exist inside the callers code.

        PadWalker

        > but I think I need more.

        I think you need to rethink your questions... ;)

        Cheers Rolf

Re: How to simulate a preprocessor macro without one?
by Anonymous Monk on Feb 08, 2010 at 01:54 UTC
    What?

      Can I easily substitute a function call with other commands in the source code at compile time without using source Filter::Util::Call etc... ?

      In another words, is it possible to define a class method which runs at compile time and expands the call to a program block instead of returning a value from the class method at the run time?

        You can redefine functions at any time ( BEGIN/RUN/CHECK/END )