【问题标题】:Template compiling in simple Perl template system [closed]简单 Perl 模板系统中的模板编译
【发布时间】:2012-08-03 19:12:35
【问题描述】:

我需要编写一个简单的模板系统,其中包含两种类型的宏——变量(如<% TPL name=userName %>)和函数(如<% TPL func=time param=now %> 或<% TPL func=rand %>)。

一切正常,但我需要添加模板编译。我想将变量宏替换为 Perl 变量(<% TPL name=userName %> 到 $userName 或 $vars->{userName})和函数到 "Some text $rand->() blah blah" 或 "Some text $func->{time}->('now') and blah blah blah"。

我是为变量做的:

my $tpl = eval 'sub { my $vars = shift; "Hello, $vars-{userName}!" }';
return $tpl->({ userName => 'John' });

但我不知道如何处理函数。此代码不起作用:

my $tpl = eval 'sub { my $func = shift; "Today is $func->{time}->('day')" }';
return $tpl->({ time => \&_time });

我怎样才能让函数工作?

附注我不需要其他模板系统(TT、HTML::Template 或其他)

【问题讨论】:

  • Perl 中提供了许多可靠的模板选项,编写另一个可以使用进一步的理由。您遇到的挑战是考虑现有替代方案的另一个原因。
  • 如果您不使用 CPAN 模块,您至少可以看看它们是如何实现的..
  • 制作模板系统很难;你为什么要创建自己的?

标签: perl templates eval


【解决方案1】:

关键部分是

"Today is $func->{time}->('day')"

这不起作用,因为您不能从字符串内部调用函数/不能插入 coderef。您可以选择以下解决方案:

"Today is " . $func->{time}->('day');

"Today is @{[$func->{time}->('day')]}";

my $today = $func->{time}->('day');
"Today is $today";

你的代码还是有问题的,因为你使用了eval 而不仅仅是一个匿名子或closure! 你可以写

my $tpl = sub {
   my ($vars) = @_;
   return "Hello, $vars->{userName}!";
};
return $tpl->({ userName => 'John' });

和

my $tpl = sub {
   my ($func) = @_;
   return "Today is $func->{time}->('day')";
};
return $tpl->({ time => \&_time });

提示:在构建这样的模板系统时,/e 选项真的很有帮助:

$template =~ s{<% func=(\w+) param=(\w+) %>}{join(' ',$hash->{$1}->($2))}e;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-10
    相关资源
    最近更新 更多