基于config遍历Perl中的哈希值

时间:2017-06-14 16:47:26

标签: perl

我需要能够从我从不同第三方收到的数据中提取特定值。根据第三方的不同,数据的结构可能不同。例如:

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);

任何想法都非常感激。

1 个答案:

答案 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 { ... },适合简单代码。请参阅perlreftutperlrefperlsub

有很多方法可以在程序中传输数据,从而实现查找本身。

以下是按步骤构建的插图。它使用(确认的)事实,即数据处于有效的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'(等)的某个地方。

以一致的方式建立数据可以极大地提高灵活性。如果代码是经过深思熟虑的,那么整个事情也可以很容易维护。

如果这变得越来越复杂,解决方案就是编写一个类。然后你可以建立一个非常好的系统。