【问题标题】:Perl- Dereferencing an arrayref and assigning the result to a variable results in variable having the value 1Perl-取消引用arrayref并将结果分配给变量会导致变量值为1
【发布时间】:2013-06-07 17:50:22
【问题描述】:

我正在尝试解析作为数组引用进入我的脚本的日志行。

我有另一个子例程,此日志行被传递给它以提取某个值,但是该函数似乎没有接收日志行而是获取值 1。当我尝试取消引用数组 ref 并分配时会发生这种情况它也是一个标量。

日志行看起来像 -

print Dumper ($logline)

$VAR1 = '2013-06-07 17:22:32.219 <TID 1B344> [uss_smm.reqserv] 162.34.22.1: "POST /ts/start/67257-v/827987/ts/june7test1/backup/20130fd83788-02-ts&action=setarchiver&timestamp=1370625752.172546&as=new2 HTTP/1.1" 200 - Success.';

Assigning the dereferenced value to scalar -
my $temp_line = @{ $logline };
print "temp_line is $temp_line \n";

temp_line is 1

子程序调用是-

my $arch = parse_Smmlog_Arch_Comm(@{ $logline }); 

解析的子程序是-

sub parse_Smmlog_Arch_Comm($){
    my $logline = shift;
    print Dumper ($logline);
    test_log(INFO,"in parse_Smmlog_Arch(), logline is  - $logline ");
    my @arr = split('&as=',$logline);
    my @sec_arr = split(' ',$arr[1]);
    return $sec_arr[0];
}

我在运行脚本时得到这个,这是因为子例程没有收到日志行。

Use of uninitialized value in split at /Users/myname/parseLog.pl

我将不胜感激。

【问题讨论】:

    标签: perl arrayref


    【解决方案1】:

    $logline 不是数组引用,它是纯字符串。

    但是,您将其视为数组引用,因此它会查找这样的数组变量:

    @{'2013-06-07 17:22:32.219 <TID 1B344> [uss_smm.reqserv] 162.34.22.1: "POST /ts/start/500000-b/500000/ts/june7test1/backup/20130607T102446-02-ts&action=setarchiver&timestamp=1370625752.172546&as=new2 HTTP/1.1" 200 - Success.'}
    

    use strict 下会失败(这可以防止您意外使用这样的符号引用)。您应该在所有代码中启用use strict;use warnings; 以捕获许多简单的错误。

    即使是数组引用,这段代码:

    my $temp_line = @{ $logline };
    

    将数组中的元素个数赋值给$temp_line;因为你得到了 1,所以你不小心在其他地方也使用了相同的符号引用,并且实际上使用奇怪的名称创建和填充了数组。

    要获取数组的第一个元素,请执行以下操作:

    ${ $logline }[0]
    

    或者要在从数组中删除它时获取它,请执行以下操作:

    shift @{ $logline }
    

    一般来说,使用引用只比使用简单的数组或哈希稍微复杂一点;请参阅http://perlmonks.org/?node=References+quick+reference 了解一些易于记忆的规则以提供帮助。

    【讨论】:

    • 非常感谢!之前的 Dumper 输出有错误。它确实是一个数组引用。我确信这一点,因为当我执行打印 $logline 时,我得到 ARRAY(0x7f9d6c6f5278)。 ${ $logline }[0] 成功了。
    • 另外,我总是使用严格和警告。前段时间学到了这一课。
    【解决方案2】:

    问题可能与您的函数原型有关:

    sub parse_Smmlog_Arch_Comm($)
    

    这意味着它需要一个标量。当您将一个数组(即@{ $logline })传递给它时,该数组将在标量上下文中进行评估,从而为您提供该数组中的元素数,即 1。

    当你执行第一个split 时,你什么也得不到,所以@arr 是空的,导致第二个split 出现uninitialized value 错误。

    $ 替换为@ 或从函数定义中删除($) 将解决问题。或者,传递一个标量作为函数的参数。


    旁注:在函数内部和外部使用相同的变量名表示不同的东西(内部字符串,外部数组引用)可能不是一个好主意

    【讨论】:

    • 谢谢,我同意变量名称位。
    猜你喜欢
    • 2012-04-09
    • 2022-01-06
    • 1970-01-01
    • 2021-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多