That is, variables like $*scalar
, @*array
and %*hash
.
I'm asking this question mainly because I want to have an idea of how much of a burden they are on the overall performance of the grammar/regex engine.
To add a bit of precision to my question, I would like to know what happens :
on lookup,
my $var-1 = $*scalar
my $var-2 = @*array[3]
my $var-3 = %*hash<key>
and on insertion,
$*scalar = "new value 1"
@*array[3] = "new value 2"
%*hash{"existing key"} = "new value 3"
%*hash{"new key"} = "new value 3"
in relationship with the symbol table, the call stack, or any data structure involved like a special stack for handling dynamical scoping, or maybe a hash table of stacks.
My main interest is with array and hashes, and if they are both entirely duplicated each time we push/pop/modify/insert an array element or insert/modify/delete a key/value pair of a hash.
EDIT:
My assumptions about dynamical scoping was wrong. I thought that, when modifying a dynamically scoped hash, the changes would be undone at the end of the lexical scope in which the change has been made, similar to what happens in Perl with the local
keyword and its associated "temporaries stack", hence my "Is the data structure duplicated ?" question. But this is not what dynamically scoped means it seems.
My assumption was that this following Raku code was equivalent to the following Perl code. Instead, to replicate the behavior of the Perl code, we must do what the 2nd piece of Raku code do.
Raku 1:
my %*hash = (key => "value");
sub test() {
say "test() start";
say "\t", %*hash;
%*hash<key>="new value";
say "\t", %*hash;
say "test() end";
}
say %*hash;
test();
say %*hash;
OUTPUT:
{key => value}
test() start
{key => value}
{key => new value}
test() end
{key => new value}
Perl
our %hash=(key => "value");
sub test {
local %hash=%hash;
say "test() start";
say "\t", %hash;
$hash{key}="new value";
say "\t", %hash;
say "test() end"
}
say %hash;
test();
say %hash;
OUTPUT:
keyvalue
test() start
keyvalue
keynew value
test() end
keyvalue
Raku 2:
my %*hash = (key => "value");
sub test() {
my %*hash=CALLERS::<%*hash>;
say "test() start";
say "\t", %*hash;
%*hash<key>="new value";
say "\t", %*hash;
say "test() end";
}
say %*hash;
test();
say %*hash;
OUTPUT:
{key => value}
test() start
{key => value}
{key => new value}
test() end
{key => value}
local
in Perl, which clearly does something different. – Suzerainty