This is not really about hard versus soft references, but about different data types that happen to have the same name. In the statements
$removed = [ @removed ];
and
$removed = \@removed;
the scalar $removed is the same thing: a hard reference to an array. In the first case, the reference is to an anonymous array created | initialized by a shallow copy from the @removed array. In the second case, the reference is directly to the @removed array. Again, both references are hard references, not soft (or symbolic) references. There are no soft references in the OPed code.
It is a "feature" of Perl that the variables $foo @foo %foo &foo and maybe a few others are all different data types which can be made to have the same name (usually a practice to be avoided, IMHO).
Update: Here's some code that might give a better idea of what's going on:
c:\@Work\Perl\monks>perl -wMstrict -le
"use Data::Dump qw(pp);
;;
my @ra = qw(a b c d);
print 'A: ', pp \@ra;
;;
my $hardref = [ @ra ];
print 'B1: ', pp $hardref;
pop @{$hardref};
print 'B2: ', pp $hardref;
print 'B3: ', pp \@ra;
;;
$hardref = \@ra;
pop @{$hardref};
print 'C1: ', pp $hardref;
print 'C2: ', pp \@ra;
"
A: ["a" .. "d"]
B1: ["a" .. "d"]
B2: ["a", "b", "c"]
B3: ["a" .. "d"]
C1: ["a", "b", "c"]
C2: ["a", "b", "c"]
Give a man a fish: <%-{-{-{-<
| [reply] [d/l] [select] |
AnomalousMonk has nailed the issue. Strictures (use strict; use warnings;) would have given you early warning that things were going wrong. Consider:
use strict;
use warnings;
my $dwarfs = [ qw(Doc Grumpy Happy Sleepy Sneezy Dopey Bashful) ];
print "@{$dwarfs}\n";
print "@dwarfs\n";
Prints:
Possible unintended interpolation of @dwarfs in string at ... line 7.
Global symbol "@dwarfs" requires explicit package name at ... line 7.
Execution of ... aborted due to compilation errors.
which should give you pause to wonder what the heck that means.
Premature optimization is the root of all job security
| [reply] [d/l] [select] |
ok : i should have used strict en warnings
use strict;
use warnings;
my $dwarfs = [ qw(Doc Grumpy Happy Sleepy Sneezy Dopey Bashful) ];
print "@{$dwarfs}\n";
my @removed=();
my $removed="";
@removed = splice @{$dwarfs},3 ,2;
#$removed = [ @removed ]; #1. please notice : this makes a copy first
+ of @removed . # changes to @{$removed} will NOT affect @removed
# OUTPUT : Sleepy Sneezy
$removed = \@removed ; #2. please notice : this is a hard reference
+. # changes to @{$removed} will affect @removed.
# OUTPUT : Sleepy
# let's examine the above : Just uncomment one of the above beginning
+ with : $removed
pop @{$removed} ;
print "@removed\n";
| [reply] [d/l] |
This is, for the most part, just a picky restatement of some points I was trying to make above. But references are tricky, so I want to make these points clearly.
The statement
$removed = [ @removed ];
creates a hard reference to an anonymous array initialized by a shallow copy from the @removed array. The statement
$removed = \@removed;
also creates a hard reference, but to the named @removed array. The nature of both these references is the same, but their referents, the things they reference, are different. Hence, the difference in behavior when using these two references.
#$removed = [ @removed ]; #1. please notice : this makes a copy first of @removed . # changes to @{$removed} will NOT affect @removed
It is not true that changes to $removed will not affect the referent. Because the anonymous array is initialized by a shallow copy, accesses by reference to lower levels of the referent, if such exist, can change the referent. E.g.:
c:\@Work\Perl\monks>perl -wMstrict -le
"use Data::Dump qw(dd);
;;
my @ra = ([ qw(fee fie foe) ], [ qw(original stuff) ], [ qw(uno dos t
+res) ]);
dd \@ra;
;;
my $hardref = [ @ra ];
dd $hardref;
print '-------------';
;;
$hardref->[1] = 'ZOT!';
$hardref->[0][2] = 'KAPOW!';
$hardref->[2][1] = 'WHAM!';
dd $hardref;
dd \@ra;
"
[
["fee", "fie", "foe"],
["original", "stuff"],
["uno", "dos", "tres"],
]
[
["fee", "fie", "foe"],
["original", "stuff"],
["uno", "dos", "tres"],
]
-------------
[["fee", "fie", "KAPOW!"], "ZOT!", ["uno", "WHAM!", "tres"]]
[
["fee", "fie", "KAPOW!"],
["original", "stuff"],
["uno", "WHAM!", "tres"],
]
Note that a change to the "top" level of the $hardref reference ('ZOT!') does not change the original content of the @ra array, but a more indirect or "lower" level access ('KAPOW!' 'WHAM!') does. As I say, tricky.
Give a man a fish: <%-{-{-{-<
| [reply] [d/l] [select] |