what is the difference between taking reference to a variable using \ and {},[] in perl?

perl

Solution

Both `\%hash` and `{%hash}` create references, but they reference two different things.

`\%hash` is a ref to `%hash`. If dereferenced, its values will change with the values in `%hash`.

`{%hash}` creates a new anonymous hash reference from the values in `%hash`. It creates a copy. It's the simplest way of creating a shallow copy of a data structure in Perl. If you alter `%hash`, this copy is not affected.

How long a variable lives has nothing to do with what kind the variable is, or how it was created. Only the scope is relevant for that. References in Perl are a special case here, because there is an internal ref counter that keeps track of references to a value, so that it is kept alive if there are still references around somewhere even if it goes out of scope. That's why this works:

sub frobnicate {
    my %hash = ( foo => 'bar' );
    return \%hash;
}

If you want to disassociate the reference from the initial value, you need to turn it into a weak reference via `weaken` from Scalar::Util. That way, the ref count will not be influenced by it, but it will still be related to the value, while a copy would not be.

See perlref and perlreftut for more information on references. This question deals with how to see the ref count. A description for that is also available in the chapter Reference Counts and Mortality in perlguts.

Problem

below code works fine but if I replace `push @array,{%hash}` with `push @array,\%hash` then it doesn't. Can someone please help me understand the difference. I believe `{%hash}` refers to an anonymous hash. Does it mean a anonymous hash lives longer than a reference to a named hash ( `\%hash` ). ``` use strict; use warnings; use Data::Dumper; my @array; my %hash; %hash = ('a' => 1, 'b' => 2, 'c' => 3,); push @array,{%hash}; %hash = ('e' => 1, 'f' => 2, 'd' => 3,); push @array,{%hash}; print Dumper \@array; ``` output ``` $VAR1 = [ { 'c' => 3, 'a' => 1, 'b' => 2 }, { 'e' => 1, 'd' => 3, 'f' => 2 } ]; ``` UPDATE Below is the actual code I am working on. I think in this case taking copy of the reference is the only possible solution I believe. Please correct me if I am wrong. ``` use Data::Dumper; use strict; use warnings; my %csv_data; my %temp_hash; my @cols_of_interest = qw(dev_file test_file diff_file status); <DATA>; #Skipping the header while (my $row = <DATA>) { chomp $row; my @array = split /,/,$row; @temp_hash{@cols_of_interest} = @array[3..$#array]; push @{$csv_data{$array[0]}{$array[1] . ':' . $array[2]}},{%temp_hash}; } print Dumper \%csv_data; __DATA__ dom,type,id,dev_file,test_file,diff_file,status A,alpha,1234,dev_file_1234_1.txt,test_file_1234_1.txt,diff_file_1234_1.txt,pass A,alpha,1234,dev_file_1234_2.txt,test_file_1234_2.txt,diff_file_1234_2.txt,fail A,alpha,1234,dev_file_1234_3.txt,test_file_1234_3.txt,diff_file_1234_3.txt,pass B,beta,4567,dev_file_4567_1.txt,test_file_4567_1.txt,diff_file_4567_1.txt,pass B,beta,4567,dev_file_4567_2.txt,test_file_4567_2.txt,diff_file_4567_2.txt,fail C,gamma,3435,dev_file_3435_1.txt,test_file_3435_1.txt,diff_file_3435_1.txt,pass D,hexa,6768,dev_file_6768_1.txt,test_file_6768_1.txt,diff_file_6768_1.txt,fail ```

Original source

Related problems