in reply to Perl generating embedded Perl

If you eval a string containing a named sub definition, it gets installed into the current package:

c:\test>perl -E"eval 'sub Foo{ return 12345 }'; print Foo();" 12345

If you want to create an anonymous sub and get a reference to it into a variable:

c:\test>perl -E"$f = eval 'sub { return 12345 }'; print $f->();" 12345 c:\test>perl -E"$f = eval 'sub { return "bar" }'; print $f->();" bar

That works also.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"I'd rather go naked than blow up my ass"

Replies are listed 'Best First'.
Re^2: Perl generating embedded Perl
by AriSoft (Sexton) on Feb 06, 2010 at 23:19 UTC

    Thank you, I thought I need to use something called "dynloader" from core which is used by source filters but this happened to be more easier that I could imagine :-)

    I got my second Perl experiment to work exactly the way I wanted by using this anonymous sub reference solution.

    Here is my extremely fast precompiled Embedded Perl HTML template for your reference.

    use 5.010; use strict; use warnings; our $start_time = time; #Embedded perl HTML template compiler object class package HTML::template; #Preloads new template object: #@_ = class, embedded perl/html input source sub new { my ($class, $input) = @_; $input //= $_; #Slurp the source template open my $fh, "<", $input or die "$! \"$input\""; local $/; my $slurp = <$fh>; close $fh; #Extract perl script from the template my $content = \$slurp; my $position = 0; my $script = "sub {\n\# line 1 \"$input\"\n"; #Scan html comment tags while ( $slurp =~ /<!--(?<cmd>.*?)-->/gso ) { #Insert text block $script .= "print substr(\${\$content},$position,$-[0]-$positi +on);\n"; #Translate line numbers my $line = ( substr($slurp,0,$position) =~ tr/\n// ) + 1; #Insert perl block using fixed line number $script .= "\# line $line\n$+{cmd}\n"; #Advance to next block $position = $+[0]; } #Insert the last text block $script .= "print substr(\${\$content},$position);}"; #Precompile script my $compiled = eval($script) or die; #Define template object list bless [$content, $compiled], $class; } #Execute the template object ##@_ = class, html output target sub run { my ($self, $output) = @_; my ($content, $compiled) = @{$self}; $output //= $_; #Redirect output local (*STDOUT); open(STDOUT, ">", $output); #Excute precompiled script $compiled->(); } #Sample program utilizing HTML::template my $sample_input = <<'END'; Numbers generated at <!--print $start_time;--><br> <!--for(my $x = 1; $x < 5; $x++) {-->Number=<!--print $x;--><br> <!--}-->Time used <!--print time - $start_time;--> seconds.<br> END my $template = HTML::template->new(\$sample_input); my $sample_output = ''; $template->run(\$sample_output); print $sample_output; #Output from sample_template Numbers generated at 1265498059<br> Number=1<br> Number=2<br> Number=3<br> Number=4<br> Time used 0 seconds.<br>
      Perl code + Template = Text::Template
      use warnings; use strict; use Text::Template qw(fill_in_string); print fill_in_string(<<'EOT'); Numbers generated at { $start_time = time }<br>{ for my $x (1 .. 4) { $OUT .= "\nNumber=$x<br>" } } Time used { time - $start_time } seconds.<br> EOT

        You are right. When I started this experiment I already knew that this will be just an another template script. Actually there were so many on them that I decided to go faster if I make my own instead of evaluating every one of already made template srcipts. I can also learn something valuable as I really did.

        I used the same approach with my first Perl program too. That was a multithreaded HTTP server. When I have tried some already available versions, which finally did not install in Windows or was too complicated to understand at my level of knowlegde. I made my own. It took days to debug because there is a bug in Windows socket code in Strawberry Perl release. (Reported: https://rt.cpan.org/Public/Bug/Display.html?id=54285)