-3

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

没关系,但我需要添加模板编译。我想用 Perl 变量(<% TPL name=userName %>to $userNameor $vars->{userName})和函数 to "Some text $rand->() blah blah"or替换变量宏"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 });

如何使功能正常工作?

PS 我不需要另一个模板系统(TT、HTML::Template 或其他)

4

1 回答 1

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";

无论如何,您的代码都病了,因为您使用 aneval而不仅仅是匿名子或闭包!你可以写

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;
于 2012-08-03T20:00:23.710 回答