$tasks->{t1}{cmdline} = "convert -f %FONT% %1%";
$tasks->{t1}{report} = "Launched as %CMD% by %USER%";
$tid = 't1';
foreach my $parm (keys %{$tasks->{$tid}}) {
$tasks->{$tid}{$parm}=~s/%FONT%/$tasks->{$tid}{font}/g; # may evaluate if $parm == 'cmdline';
$tasks->{$tid}{$parm}=~s/%CMD%/$tasks->{$tid}{cmdline}/g;
}
代码很糟糕,因为它需要在foreach之外的另一个循环(以确保替换所有复制的值),并且还包含太多的文本数据。目前重写的最佳方式如下:
foreach my $parm (keys %{$tasks->{$tid}}) {
&lookupValues(\$tasks->{$tid}{&parm}); # or ($parm) if strict refs?
}
但是,为了检测优先级,仍需要对密钥进行排序(如果在%FONT%,$ tasks-> {$ tid} {report}错误之前更换了%CMD%)。
foreach my $parm ( &SORTME($tasks->{$tid}) ) {&lookupValuesFor($tid,$parm); }
根据指定变量的数量及其关系,排序的最佳方法是什么?原生的(很多循环和散列),或expat [相关问题以某种方式指向我expat,也会调查它:Parsing a string for nested patterns]或其他解析器?
现在不喜欢$ object->值('cmdline')的OOP方式。
答案 0 :(得分:2)
此代码“有效” - 对我来说看起来更干净。它是否能满足您的需求是值得商榷的。
use strict;
use warnings;
my $tasks;
# Demonstration setup
$tasks->{t1}{cmdline} = "convert -f %FONT% %1%";
$tasks->{t1}{report} = "Launched as %CMD% by %USER%";
$tasks->{t1}{maps} = {
'%USER%' => 'user-expansion',
'%1%' => 'one-expansion',
'%FONT%' => 'font-expansion',
'%CMD%' => 'cmd-expansion',
};
# Do the substitutions
foreach my $tid (keys %$tasks)
{
my $task = $tasks->{$tid};
my $maps = $task->{maps};
foreach my $map (keys %$maps)
{
foreach my $key (keys %{$task})
{
next if ref $task->{$key};
$task->{$key} =~ s/$map/$maps->{$map}/g;
}
}
}
# Demonstration printing
foreach my $tid (keys %$tasks)
{
my $task = $tasks->{$tid};
foreach my $key (keys %{$task})
{
next if ref $task->{$key};
printf "%s: %-8s = %s\n", $tid, "$key:", $task->{$key};
}
}
在MacOS X(10.6.4)上使用Perl 5.13.4的输出是:
t1: report: = Launched as cmd-expansion by user-expansion
t1: cmdline: = convert -f font-expansion one-expansion
三重循环接近不可避免;您希望将每个映射应用于每个任务的每个字符串。一般来说,每个任务都可以有自己的映射。