On Wed, Feb 12, 2020 at 10:27:20AM -0300, Aureliano Guedes wrote:
> So, I'd like to find a way to test if two variables are bound or not,
> especially concerning their memory address.
>
> If the address is not fixed for a lifetime, I must be able to test it in
> just one cycle.
> > $a.WHERE == $b.WHERE # I expected FALSE
> True
>
> To a bound variable, I expect the same address, but to an unbounded
> variable, this garbage collector behavior seams assing to the same memory
> location two unbounded variables with the same value. It is right? Must
> reduce memory usage but is a quiet weirdo.
I don't know that it's "weirdo" that two variables containing the same
(constant, immutable) value end up at the same address. It's just the compiler
treating constants as proper objects and being smart about memory allocation.
In particular:
> my $a = 3; say $a.WHERE
94659198947472
> $a = 4; say $a.WHERE
94659198947432
> $a = 3; say $a.WHERE
94659198947472
What's likely happened is that the compiler has created an Int representing the
constant "3", and keeps track of that for future compilations. Whenever the
compiler encounters another "3", rather than build a new Int object in memory
it re-uses the Int it already established if it can.
So, with
> my $b = 3; say $b.WHERE
94659198947472
The compiler lets $b use the same constant 3 object that was created the first
time it was encountered, even though $a coincidentally also uses it.
> $b = 6 div 2; say $b; say $b.WHERE
3
139719166700504
The compiler has gone ahead and used "6 div 2" to produce a new Int object,
which has the same value as the constant 3 but is in a different memory
location. If we then do
> $b = 3; say $b.WHERE
94659198947472
you can see that the constant "3" Int is still hanging around to be used
wherever it's later mentioned in the code.
Hope this helps,
Pm