【问题标题】:Dynamic function injection into Text::Template namespace动态函数注入到 Text::Template 命名空间
【发布时间】:2014-12-11 23:32:01
【问题描述】:

我正在使用以下语法将函数注入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
}

【问题讨论】:

    标签: perl texttemplate


    【解决方案1】:

    无需猜测内部结构。使用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
    

    【讨论】:

    • 谢谢!有必要这样做的另一个原因是因为简单地添加整个子 sub my_sub {...} 会导致各种 sub already defined 错误,因为 Text::Template 没有选项只能添加一次。看起来像是一个疏忽,除非我错过了......
    【解决方案2】:

    这应该可行:

    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
    }
    

    【讨论】:

    • 我保留了您的foreach 结构,但您也可以将其替换为foreach my $i (0 .. $#items),以免保留单独的计数器
    猜你喜欢
    • 1970-01-01
    • 2010-09-14
    • 2018-07-31
    • 1970-01-01
    • 2012-10-20
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    相关资源
    最近更新 更多