Documentation for declarator my assembled from the following pages:

Language documentation: Variables §

From Variables

(Variables) declarator my §

Declaring a variable with my gives it lexical scope. This means it only exists within the current block. For example:

{
    my $foo = "bar";
    say $foo; # OUTPUT: «"bar"␤»
}
say $foo; # Exception! "Variable '$foo' is not declared"

This dies because $foo is only defined as long as we are in the same scope.

In order to create more than one variable with a lexical scope in the same sentence surround the variables with parentheses:

my ( $foo$bar );

see also Declaring a list of variables with lexical or package scope.

Additionally, lexical scoping means that variables can be temporarily redefined in a new scope:

my $location = "outside";
 
sub outer-location {
    # Not redefined: 
    say $location;
}
 
outer-location# OUTPUT: «outside␤» 
 
sub in-building {
    my $location = "inside";
    say $location;
}
 
in-building;    # OUTPUT: «inside␤» 
 
outer-location# OUTPUT: «outside␤»

If a variable has been redefined, any code that referenced the outer variable will continue to reference the outer variable. So here, &outer-location still prints the outer $location:

sub new-location {
    my $location = "nowhere";
    outer-location;
}

new-location; # OUTPUT: «outside␤»

To make new-location() print nowhere, make $location a dynamic variable using the * twigil. This twigil makes the compiler look up the symbol in the calling scope instead of the outer scope after trying the local scope.

my is the default scope for subroutines, so my sub x() {} and sub x() {} do exactly the same thing.