When you write this:
my $a = 'b';
$a = 'c';
say $a;
What happens is something that is sort-of like this:
my $a := Scalar.new( value => 'b' );
$a.set-value('c');
say $a.get-value();
Basically a new Scalar object is created and $a
is a pointer to it.
Of course it isn't quite that simple as you can't even call .new
on a Scalar and have it do anything.
There is also a lot more information stored inside of the Scalar object.
For example the type information and any default.
Really what you think about $
variables is all contained inside of the Scalar object.
Normally this container tries to be completely transparent.
You can however get at the Scalar object with the .VAR
method/macro.
my Int $a is default(42) = 3;
my $var = $a.VAR;
say $var.name; # $a
say $var.of; # (Int)
say $var.default; # 42
say $var.self; # 3
There are other ways that this transparency gets more translucent than transparent.
sub foo ( \v ){ # the \ is so it isn't seen as a Type name
say v.VAR.name
v = 22;
}
foo $a; # $a
say $a; # 22
That is because the Scalar gets passed to the subroutine, not the value inside of the Scalar.
The Scalar is always passed to the function call, it's just that the function often decides to do something other than allowing you raw access to the original Scalar.
In the following, the value inside of the passed Scalar is copied to a new Scalar that doesn't allow modification.
sub bar ( $v ){
# $v = 3; # ERROR
}
bar $a
If you had declared $v
as is rw
or is raw
, $v
would actually be a pointer to the Scalar container you passed in just like \v
above. (\v
is very similar to is raw
.)