使用解引用块的动态变量名

Perl非常灵活,允许你使用语言实现各种神奇的功能。其中一个例子是使用解引用块将标量值用作变量名。这允许你使用具有动态名称的变量。

Nginx::ParseLog中可以看到这个例子,我已经复制了相关代码

if ( $log_string =~ m/^($ip)\s-\s (.*?)\s         \[(.*?)\]\s  "(.*?)"\s  (\d+)\s  (\d+)\s     "(.*?)"\s  "(.*?)"$/x) {
    my $deparsed = { };
    my $c = 0;
         
    my @field_list = qw/
            ip     
        remote_user
            time    
            request
            status 
            bytes_send
            referer 
            user_agent
    /;
 
    {
        no strict 'refs'; # some Perl magic
 
        for (@field_list) {
            $deparsed->{ $_  } = ${ ++$c };
            }
    }
     
    return $deparsed;
}

这段代码执行的操作是将$log_string与正则表达式匹配 - 如果匹配成功,它将遍历正则表达式捕获的全球变量($1-$8),使用@field_list的值作为捕获的键值。动态变量名存储在$c中。

在适当的上下文中使用动态变量名可以提供有用的快捷方式。动态变量也可能会增加出错的风险(注意,为了使此代码工作,必须禁用strict 'refs')。这个例子中令人欣赏的是,在if语句中使用正则表达式匹配提供了确保每个捕获都成功的保证,因此在这种情况下,可以暂时关闭strict refs。


这篇文章最初发布在PerlTricks.com

标签

David Farrell

David是一位职业程序员,他经常推文博客关于代码和编程的艺术。

浏览他们的文章

反馈

这篇文章有问题吗?请在GitHub上打开一个问题或拉取请求来帮助我们。