1

Please have a look at bellow code. File contain test.csv

aa,OPEN,TEMP1
bb,CLOSE,TEMP2
cc,OPEN,TEMP3
dd,TERMINATED,TEMP4

Code:

use Data::Dumper;
sub main {
    my $file = 'test.csv';  
    my @lines1;
    my @values;

    unless (open (INPUT, $file)) {
        print " files does not exist";
    }   
    while (my $line = <INPUT>) {                
         @values = split /\s*,\s*/, $line;    
         push  @lines1, \@values;   
    }   
    foreach my $rr(@lines1) {
        print  Dumper ($rr)."\n";
    }
    close INPUT;
}
main();

CODE RESULT:

$VAR1 = [
          'dd',
          'TERMINATED',
          'TEMP4
'
        ];

$VAR1 = [
          'dd',
          'TERMINATED',
          'TEMP4
'
        ];

$VAR1 = [
          'dd',
          'TERMINATED',
          'TEMP4
'
        ];

$VAR1 = [
          'dd',
          'TERMINATED',
          'TEMP4
'
        ];

Now when I run the code all I get is last line printed 4 times. but I declare array @values inside while loop everything works fine. Can someone please explain me this strange behaviour.?

Thanks

7
  • Define variables in smallest scope possible, my @values = split /\s*,\s*/, $line; as @values doesn't need to be visible outside while loop, and as a side effect you get rid of unwanted behavior. Commented Nov 17, 2014 at 10:45
  • is this side effect or bug or correct behavior..? what is it exactly? cause i am over writing rather than appending values in array every time loop runs. so i belive it is appneding the values and then next time it is overwritting it? is this correct? Commented Nov 17, 2014 at 10:55
  • It is correct behavior, as you're always referring to same variable/(memory location) @values array => print \@values, "\n"; Commented Nov 17, 2014 at 10:59
  • any suggestion what i should do/read to get good theoretical knowledge of perl, right now i am just referring to some tutorials on youtube to learn perl Commented Nov 17, 2014 at 11:11
  • 1
    Plenty of good Perl tutorials listed at perl-tutorial.org. Just searching YouTube is almost certainly going to find stuff by people who only think they know Perl :-/ Commented Nov 17, 2014 at 11:14

2 Answers 2

3

Your problem is that you only have a single @values array and each time round your loop, you just overwrite the values in that same array. So you end up with multiple references to the same array which contains the last set of values that you put into it.

One solution is to create a new @values array each time you go round the loop.

while (my $line = <INPUT>) {               
  my @values = split /\s*,\s*/, $line;   
  push  @lines1, \@values;  
}

Another alternative is to take a copy of the array and push that reference onto @lines1.

while (my $line = <INPUT>) {               
  my @values = split /\s*,\s*/, $line;   
  push  @lines1, [ @values ];
}
Sign up to request clarification or add additional context in comments.

Comments

3

The reason is that when you declare @values at the begining it is the same array value. So you take a reference to the same array so each loop overwrites the previous declaration. However if you declare the array in the loop then at the wnd of each iteration the array falls out of scope amd no longer points to the value. Then during the next iteration, the array is redecared with a new value.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.