我需要能够从我从不同第三方收到的数据中提取特定值。根据第三方的不同,数据的结构可能不同。例如:
my $first =
{
email => "joe\@example.com",
firstname => "Joe",
lastname => "Regular",
};
my $second =
{
user => {
e-mail => "joe\@example.com",
firstName => "Joe",
lastName => "Regular",
}
};
我知道每个第三方的数据结构是什么,所以我可以将其定义为config。我最终想要的是
my $email = _magic($first_config,$first);
my $other_email = _magic($second_config,$second);
任何想法都非常感激。
答案 0 :(得分:5)
建立一个查找表。并且您可以使用调度表,使用代码引用的值进行散列,这样当使用聚会标识作为密钥时,该方的代码就会执行
my %get_value = ( first => \&fetch_first, second => \&fetch_second );
my $party = 'first'; # input via command-line options, STDIN ...
my $email = $get_value{$party}->();
其中\&fetch_first
是对子例程fetch_first
的引用。您也可以直接输入first => sub { ... }
,适合简单代码。请参阅perlreftut,perlref和perlsub。
有很多方法可以在程序中传输数据,从而实现查找本身。
以下是按步骤构建的插图。它使用(确认的)事实,即数据处于有效的Perl数据结构中,为简单起见,它指定了每个子数据中的数据。
sub fetch_first {
my $data = {
email => '...',
firstName => '...',
};
return $data->{email};
}
这只会提供电子邮件地址,但我们可以做得更好。
一旦取消引用代码引用,您也可以传递参数
my $first_name = $get_value{$party}->('firstName');
现在编写sub以使用此输入返回必填字段
sub fetch_first {
my ($query) = @_;
my $data = {
email => '...',
firstName => '...',
};
return $data->{$query};
}
上述的一个很大的缺点是调用代码必须使用有效的密钥名称,因此它需要知道它正在使用的实现细节。
这可以通过为调用选择一个漂亮的接口来改进,然后在sub中将其转换为键名(或通过另一个查找结构)。然后你打电话,如
my $email = $get_value{$party}->('email'); # or: 'first', 'last'
并且您可以查找某个联盟first => 'firstName'
(等)的某个地方。
以一致的方式建立数据可以极大地提高灵活性。如果代码是经过深思熟虑的,那么整个事情也可以很容易维护。
如果这变得越来越复杂,解决方案就是编写一个类。然后你可以建立一个非常好的系统。