*
ErrorsCollection

*

Synthesised documentation from language/variables

From language/variables

See Original text in context

This twigil is used for dynamic variables which are looked up through the caller's, not through the outer, scope. Look at the example below.[1]

my $lexical   = 1;
my $*dynamic1 = 10;
my $*dynamic2 = 100;
 
sub say-all() {
    say "$lexical$*dynamic1$*dynamic2";
}
 
say-all();    # OUTPUT: 1, 10, 100 
 
{
    my $lexical   = 2;
    my $*dynamic1 = 11;
    $*dynamic2    = 101;
 
    say-all(); # OUTPUT: 1, 11, 101 
}
 
say-all();  # OUTPUT: 1, 10, 101 

The first time &say-all is called, it prints "1, 10, 100" just as one would expect. The second time though, it prints "1, 11, 101". This is because $lexical isn't looked up in the caller's scope but in the scope &say-all was defined in. The two dynamic variables are looked up in the caller's scope and therefore have the values 11 and 101. The third time &say-all is called $*dynamic1 isn't 11 anymore, but $*dynamic2 is still 101. This stems from the fact that we declared a new dynamic variable $*dynamic1 in the block and did not assign to the old variable as we did with $*dynamic2.

The dynamic variables differ from other variable types in that referring to an undeclared dynamic variable is not a compile time error but a runtime failure, so a dynamic variable can be used undeclared as long as it's checked for definedness or used in a Boolean context before using it for anything else:

sub foo() {
    $*FOO // 'foo';
}
 
say foo# OUTPUT: «foo␤» 
 
my $*FOO = 'bar';
 
say foo# OUTPUT: «bar␤» 

Dynamic variables can have lexical scope when declared with my or package scope when declared with our. Dynamic resolution and resolution through symbol tables introduced with our are two orthogonal issues.