【发布时间】:2016-08-10 15:19:34
【问题描述】:
如果此问题已在其他地方提出和/或回答,请原谅我。
在我开始之前,我应该指出,此查询的性质可能不需要将代码添加到此线程,而答案可能只是指向模板工具包模块文档的链接,并带有注释“再读一遍” :)。更清楚地说,我会接受一个简洁的“是”或“否”答案。
假设我有一个可以正常工作的 perl 脚本,它可以毫无问题地处理 Template::Toolkit 模板。
但是,我的一个模板包含“名称”(人名、服务器名称,最后真的没关系:只是“名称”)。这些名称用于稍后创建包含已处理数据的 FILENAMES。
今天,我通过以下伪代码进行了这项工作:
$template->process('names.tt','output.txt');
然后,我在“output.txt”中获取生成的“名称”列表,并将它们推送到同一执行 Perl 脚本中的数组中。然后以迭代方式使用此列表以输出在另一个模板中指定的数据,并根据原始“名称”命名每个结果文件:
foreach(@names){
my $filename = $_ . '.txt';
$template->process('profile_doc.tt',$filename)
}
正如我所说,这一切都很好(实际上是完美的)。我的问题是它不必要地使我的代码膨胀(必须管理开放的 FH 等)。鉴于 TT 的非凡能力,肯定有更好的方法。
所以我开始阅读 Template::Toolkit 的包含模块(例如:STASH、PROVIDER 等)。例如,我了解 STASH 允许您以补充方式将数据注入现有的模板模块对象,但这与我想要做的截然相反。
我的实际问题(同样,YES 或 NO 可以作为答案是否可行):
Perl 脚本是否有可能读取一个模板,比如一个包含 Template-Toolkit 存储的 HASH 对象的模板,然后创建一个可用的新 HASH通过实际的 Perl 脚本(例如:在模板之外)?
如果这是可能的,它将不需要以复杂的方式从一个模板中提取数据并使用该数据来处理另一个模板。相反,我理论上可以执行以下操作,而无需手动填充需要写入磁盘然后通过 FH 再次读取的列表。
foreach(sort keys $derivedhash{obj}){
$filename = $_->{name} . '.txt';
$template->process('profile_doc.tt',$_->{name});
}
谢谢,请理解我已尽最大努力创建一个可用的伪模型,因为真正的代码涉及机密元素,遗憾的是,它排除了泄露。我希望你会明白。我可以根据需要提供其他“经过整理的抽象/示例”。
更新
回应用户ikegami:
首先,感谢您的回复。
好的,让我们从你的一个 cmets 开始:“......这没有任何意义,因为 TT 不存储哈希值”......嗯......除非我们在谈论两个不同的事情,否则这是不正确的,因为我今天正在这样做.. 例如,这是一个模板托管的对象,其中包含我所说的初始哈希的元素:
[%- SERVERS = [
{entry={
NAME => 'Server1'
SERIAL => '1234567890'
DESC => 'A file server'
}}
{entry={
NAME => 'Server2'
SERIAL => '0987654321'
DESC => 'An account server'
}}
]-%]
再一次,上面的东西是有效的,它确实存在于 TT 中............除非我弄错了,上面的东西看起来、感觉和尝起来肯定像一个哈希......我但是,请允许您将它包含在一个数组中......所以也许它不是一个 100% 的 A 级“纯 HASH 对象”,但我当然会像哈希一样利用它(而且也非常好)。
在你说什么之前,我已经认识到我很可能需要将 key 名称更新为 UNIQUE 以便于解析(哈希键本身应该是唯一的),但这是单独的努力。
当您说“这显然不是您要问的”时,您是正确的。按照您的要求,让我更清楚地说明最终问题:
可以模板工具包,从正在执行的 Perl 脚本中读取包含单个 HASH 对象(如上所述)的“模板 1”,并将所述 HASH 结构读入 仅存在于所述执行脚本中的新的 散列对象(与模板本身相反)?这个“新哈希”最终将用于命名“模板 2”生成的文件。
最后,满足您的最后一个要求:
上面的输入摘录提供了您请求的“输入”。我想要的输出是从被调用模板中的数据派生的真正 Perl 哈希。
所以作为 Perl 等价物(期望的输出):
%newhash = (
entry => {
NAME => "Server1",
SERIAL => "1234567890",
DESC => "A file server"
},
.... other entries ....
);
.... 将用于将特定值(例如“NAME”值)“提供”给“稍后”处理的其他模板。
我希望这能消除混乱...再次感谢 ikegami ...
【问题讨论】:
-
您可以提供一个子程序引用作为
process()的第三个参数,生成的输出将作为参数传递;然后,您可以同时编写输出并对其进行解析,而无需再次读取文件。不过,这似乎仍然很迂回。 -
为什么要使用 TT 来生成姓名列表?这似乎在 Perl 中做得更好; TT 非常灵活,但请注意不要过多地使用模板引擎。
-
这听起来很像你在
names.tt中为模板工具包编写的任何东西都应该用 Perl 编写。 Perl 可以做 TT 可以做的所有事情,除此之外还有很多。看起来模板没有参数,所以只是通过组合文字字符串来创建名称;对吗? -
@verteron:关于您在下方“答案”下方的评论,我并不是建议您将其作为评论发布。您的问题下方有一个 edit 链接,该链接也链接到我的评论中。应通过编辑您的问题来添加任何重要的附加信息,而不仅仅是对评论的回答。在 Stack Exchange 上发布为 Answer 的任何内容都必须是原始问题的解决方案。
标签: perl template-toolkit