2014-12-10 24 views
2

我使用下面的语法注入功能分为Text::Template所以它知道该函数的使用fill_in()时:动态函数注入文本::模板命名空间

*Text::Template::GEN0::some_function = *SomeLibrary::some_function; 

我注意到,如果fill_in()被称为多一次,GEN0变为GEN1,然后GEN2 ...等等。

所以这只适用于fill_in被调用一次,因为只有GEN0命名空间被使用。

如何动态注入some_function到每个使用的命名空间?我知道它是这样的,但我不知道语法我会原封不动地使用:

my $i = 0; 
foreach my $item (@$items) { 
    # *Text::Template::GEN{i}::some_function = *SomeLibrary::some_function; 
    $i++; 

    # Call fill_in here 
} 

回答

4

不需要在内部猜测。使用PREPEND选项:

use strict; 
use warnings; 

use Text::Template; 

sub MyStuff::foo { 'foo is not bar' }; 

my $tpl = Text::Template->new( 
        TYPE => 'STRING', 
        SOURCE => "{ foo() }\n", 
        PREPEND => '*foo = \&MyStuff::foo', 
       ); 


print $tpl->fill_in; 

结果:

% perl tt.pl 
foo is not bar 
+0

谢谢!另一个需要这样做的原因是因为简单地在前面加上子sub my_sub {...}会导致各种'sub already defined'错误,因为Text :: Template没有选择只添加一次的选项。似乎相当疏忽,除非我错过了... – 2015-02-06 09:57:12

3

这应该工作:

my $i = 0; 
foreach my $item (@$items) { 
    my $str = "Text::Template::GEN${i}::some_function"; 
    no strict "refs"; 
    *$str = *SomeLibrary::some_function; 
    *$str if 0; # To silence warnings 
    use strict "refs" 
    $i++; 

    # Call fill_in here 
} 
+3

我一直在你的'foreach'结构,但你也可以将其替换为'我的foreach $ I(0 .. $#项目)'相反,以免保留一个单独的柜台 – DVK 2014-12-10 23:49:11