Scope: my, our, local, state

Lexical (enclosing block or file) The default for almost all variables

Lexical alias to a package (global) variable Package globals (our $VERSION, our @ISA, our @EXPORT_OK)

Dynamic: temporarily changes a global's value until the scope exits

Special variables (local $/, local $_, local $@) Lexical, but initialized once and persistent across calls (5.10+) Counters, caches

use strict requires declaring variables (with my/our/state) or fully qualifying them ($main::x). Always use it (use v5.12+ enables strict automatically).

use v5.36;
our $DEBUG = 0;                     # package variable $main::DEBUG

sub counter {
    state $count = 0;               # initialized only once
    return ++$count;
}
say counter() for 1..3;             # 1 2 3

sub slurp($file) {
    open my $fh, '<', $file or die "Can't open $file: $!";
    local $/;                       # undef the record separator within this scope: slurp mode
    return <$fh>;
}

sub show { say "DEBUG is $DEBUG" }
sub test {
    local $DEBUG = 1;               # dynamic scope: visible to show() called from here
    show();                         # DEBUG is 1
}
test(); show();                     # DEBUG is 0 again

my $x = 10;
{
    my $x = 20;                     # shadows the outer $x
    say $x;                         # 20
}
say $x;                             # 10