2012-08-03 74 views
-3

我需要编写一个简单的模板系统,使用两种类型的宏 - 变量(如<% TPL name=userName %>)和函数(如<% TPL func=time param=now %><% TPL func=rand %>)。在简单的Perl模板系统中编译模板

这一切都很好,但我需要添加模板编译。我想替换变量宏用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 ::模板或其他)

+4

拥有一批坚实的模板的在Perl中可用的选项,写另一个可以使用更多的理由。您遇到的挑战是考虑现有替代方案的另一个原因。 – 2012-08-03 19:28:01

+1

如果你不使用CPAN模块,你至少可以看看它们是如何实现的。 – 2012-08-03 19:46:07

+0

制作模板系统很难;你为什么试图创造自己的? – 2012-10-13 00:12:06

回答

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;