In Raku a scalar might be immutable or it might be an actual variable:
my $a := 6; # constant
my $b = 6; # variable
Is there a programmatic way to check whether a scalar is immutable without just trying to change it and seeing if it works?
An object is mutable if it is not immutable. An object is immutable if it consists, recursively, of only immutable-typed sub-objects. Thus, a tuple of lists is mutable; you cannot replace the elements of the tuple, but you can modify them through the list interface, changing the overall data.
There are no general tests for immutability. An object is immutable only if none of its methods can mutate the underlying data. the answer says: 1) Keys must not be mutable, unless you have a user-defined class that is hashable but also mutable.
What's an Immutable Object? An immutable object is an object whose internal state remains constant after it has been entirely created.
First, a slight terminological correction (not to be nitpicky, but just because this area is a bit tricky and being precise with our terms can help).
It's not really right to say that my $a := 6
is a constant; that expression binds $a
to the value 6
, which prevents you from assigning a different value to $a (with the =
operator). However, you can still rebind a new value to $a
(with the :=
operator). This means that $a
can still, in a sense, be mutated – or, at least, can be made to point to something new. For a truly constant $a
, you should use either constant $a
or change $a
to a sigil-less variable (my \a = 6
).
Now to the actual answer to your question: To determine whether $a
is bound or assigned to a value, you can use $a.VAR.WHAT
. If $a
is assigned a value, this will return the type of container, (Scalar)
; if it is bound, then it will return the type of the bound value.
As far as I know, there isn't a way to tell the difference between an $a
bound to a value and one that's a constant, though I would love to be wrong about that.
The code below illustrates what I just said:
my $a = 1;
say $a.VAR.WHAT; # OUTPUT: «(Scalar)»
$a = 2;
say $a; # OUTPUT: «2»
my $b := 1;
say $b.VAR.WHAT;# OUTPUT: «(Int)»
$b := 2;
say $b; # OUTPUT: «2»
constant $c = 1;
say $c.VAR.WHAT; # OUTPUT: «(Int)»
# $c := 2; ILLEGAL
say $c; # OUTPUT: «1»
Another way, using multiple dispatch:
my $a := 6; # constant
my $b = 6; # variable
multi sub mutable($ is rw) { True }
multi sub mutable($) { False }
say mutable($a); # False
say mutable($b); # True
say mutable(42); # False
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With