Perl- Dereferencing an arrayref and assigning the result to a variable results in variable having the value 1

StackOverflow https://stackoverflow.com/questions/16990115

  •  31-05-2022
  •  | 
  •  

Question

I am trying to parse a log line which comes in to my script as an array reference.

I have another subroutine to which this log line is passed to extract a certain value, however the function does not seem to receive the log line and instead gets the value 1. This happens when I try to dereference the array ref and assign it to a scalar as well.

The log line looks like -

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

The subroutine call is -

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

The subroutine for parsing is -

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];
}

I get this upon running the script, which is because the subroutine doesn't receive the log line.

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

I would appreciate any help on this.

Was it helpful?

Solution

$logline is not an array reference, it is a plain string.

However, you are treating it as an array reference, so it looks for an array variable like this:

@{'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.'}

which would have failed under use strict (which keeps you from accidentally using symbolic references like this). You should enable use strict; and use warnings; in all your code to catch many simple errors.

Even if it had been an array reference, this code:

my $temp_line = @{ $logline };

assigns the number of elements in the array to $temp_line; because you are getting 1, you are accidentally using the same symbolic reference somewhere else as well and actually creating and populating the array with the bizarre name.

To get the first element of an array, do:

${ $logline }[0]

or to get it while removing it from the array, do:

shift @{ $logline }

In general, using references is only slightly more complicated than using simple arrays or hashes; see http://perlmonks.org/?node=References+quick+reference for some easy to remember rules to help.

OTHER TIPS

The problem probably has to do with your function prototype:

sub parse_Smmlog_Arch_Comm($)

which means it is expecting a scalar. When you pass an array to it, namely @{ $logline }, the array is evaluated in scalar context, giving you the number of elements in that array, which is 1.

When you do the first split, you get nothing, so @arr is empty, leading to the uninitialized value error on the second split.

Replacing the $ with @ or removing ($) from the function definition would fix the problem. Alternatively, pass a scalar as the function's argument.


Sidenote: probably not a good idea to have the same variable name meaning different things inside and outside a function (a string inside, an array reference outside)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top