Containers, Binding and Itemization
13.1 Assignment vs Binding
my $a = 1;
my $b = $a; # assignment: copies the value into $b's container
$b = 2;
say $a; # 1
my $c := $a; # binding: $c is now the SAME container as $a
$c = 5;
say $a; # 5
say $a =:= $c; # True (container identity)
my $readonly := 42; # bound to a value, not a container
# $readonly = 1; # error: Cannot assign to an immutable value
my @arr := (1, 2, 3); # @arr is the List itself (immutable)
my \sigilless = 10; # sigilless: binding13.2 Scalar Containers and Itemization
Rule of thumb: @ and % variables iterate their contents. $ variables are treated as a single item. Use | (slip) to flatten into argument lists or outer lists.
my @nested = [1, 2], [3, 4];
say @nested.elems; # 2
for @nested -> $item { say $item } # [1 2] then [3 4]
my @flat = flat @nested;
say @flat; # [1 2 3 4]
my $aref = [1, 2, 3]; # an Array in a Scalar container (itemized)
for $aref { .say } # ONE iteration: prints [1 2 3]
for @$aref { .say } # three iterations (decontainerize with @ or .list)
for $aref.list { .say }
say (1, (2, 3)).elems; # 2
say (1, $(2, 3)).flat; # (1 (2 3)): $( ) itemizes, preventing flattening
say (1, |(2, 3)).elems; # 3: | slips (flattens) into the outer list
my $x = (1, 2);
say $x.VAR.WHAT; # (Scalar)
say $x<>.WHAT; # (List) (<> decontainerizes)13.3 Proxy and is rw
sub first-elem(@a) is rw { @a[0] } # return the container, not the value
my @list = 1, 2, 3;
first-elem(@list) = 99;
say @list; # [99 2 3]
my $celsius = 0;
my $fahrenheit := Proxy.new(
FETCH => method () { $celsius * 9 / 5 + 32 },
STORE => method ($new) { $celsius = ($new - 32) * 5 / 9 },
);
$fahrenheit = 212;
say $celsius; # 100