Reputation: 1237
I wanted to make a variable reference its own content so I did this:
$x=\$x;
but that does not work as I expected, $x
became a reference to itself so $$x
is the same as $x
. What I was expecting is that $$x
becomes the original string. Why is that and how should I write it correctly without making a copy of the string in $x
? Because in some cases $x
can be a huge string.
Upvotes: 4
Views: 431
Reputation: 386656
What you are asking is impossible. A variable can't contain both a reference and a string. You must utilize two variables. This leaves you with two options.
Store the reference in a new variable
$ perl -e'
use feature qw( say );
my $x = "abc";
my $y = \$x;
say $y;
say $$y;
'
SCALAR(0x232a398)
abc
Nice and simple, efficient, and no confusion as to what the variable contains at what time.
The downside of this approach is that references to the original $x
won't see the change. It's hard to imagine a situation where this would matter, however.
Note that the new var could even have the same name as the old one. I don't recommend this as it's needlessly confusing and error-prone.
$ perl -e'
use feature qw( say );
my $x = "abc";
my $x = \$x;
say $x;
say $$x;
'
SCALAR(0x232a398)
abc
Store the value in a new variable
$ perl -e'
use feature qw( say );
my $x = "abc";
$x = \( my $container = $x );
say $x;
say $$x;
'
SCALAR(0x175cbe0)
abc
The downside of this approach is it involves copying the string. However, that's only the case until 5.20. 5.20 introduced a copy-on-write mechanism for strings. That means the above won't actually copy the string in 5.20+; it will just copy a pointer instead. Note that both scalars share the same string buffer (0x2ac53d0
) in the following example:
$ perl -MDevel::Peek -e'my $x = "abc"; my $y = $x; Dump($_) for $x, $y;' 2>&1 \
| grep -P '^(?:SV| FLAGS| PV)\b'
SV = PV(0x2a9f0c0) at 0x2abcdc8
FLAGS = (POK,IsCOW,pPOK)
PV = 0x2ac53d0 "abc"\0
SV = PV(0x2a9f150) at 0x2abcde0
FLAGS = (POK,IsCOW,pPOK)
PV = 0x2ac53d0 "abc"\0
While $x = \"$x"
has been suggested as a shorter version of $x = \( my $container = $x );
, it forces stringification, and it copies the entire string, even in versions of Perl that support COW.
Upvotes: 4
Reputation: 242333
Assign a reference to the value, not to the variable:
my $string = 'abcefgh';
$string = \ "$string";
print $$string, "\n";
Upvotes: 1