--- name: my signature: 'my VARLIST' since: 5.0 status: documented categories: ["Scoping"] --- ```{index} single: my; Perl built-in ``` *[Scoping](../perlfunc-by-category)* # my Declare one or more lexically scoped variables. `my` introduces new variables whose visibility is bounded by the enclosing block, file, or [`eval`](eval). The compiler records the declaration at compile time; the storage is allocated and (re)initialised each time control enters the scope. Unlike [`local`](local), `my` does not temporarily replace a package variable — it creates a genuinely new variable that exists only while the scope is live and is invisible outside it, including to any subroutines the scope calls. ## Synopsis ```perl my EXPR my TYPE EXPR my EXPR : ATTRS my TYPE EXPR : ATTRS ``` A single variable may be written without parentheses; a list of two or more must be parenthesised: ```perl my $x; my ($a, $b, @rest); my Foo $obj; my $x : shared = 0; ``` ## What you get back `my` is a declaration, not a value-producing operator in the ordinary sense. In rvalue position it yields its variable (or the list of variables) as an lvalue you can assign to. The common idioms are: ```perl my $x = $expr; # scalar context on RHS my ($first, @rest) = @list; # list context on RHS; destructuring my @copy = @src; # list context; @copy gets the elements my %h = @pairs; # list context; pairs populate the hash ``` When no initialiser is given, each declared variable starts as [`undef`](undef) (scalar), empty list (array), or empty hash. ## Scope and lifetime - **Block scope.** A `my` variable is visible from the point immediately after its declaration to the end of the innermost enclosing block, file, `eval`, `do`, `require`, or `use`'d file. - **Control-expression scope.** The controlling expression of `if` / `unless` / `elsif` / `else`, `while` / `until`, `for` / `foreach` is part of the scope of the declaration it contains. In `while (my $line = <$fh>) { ... }` the variable `$line` is live throughout the loop body and its `continue` block, but not beyond. - **Fresh storage on every entry.** Each time control re-enters the scope, the variable is created anew. This is the key difference from [`state`](state), which preserves its value across entries. - **Closures capture storage, not values.** An anonymous sub created inside the scope keeps that particular instance of the variable alive for as long as the sub is reachable. ```perl sub make_counter { my $n = 0; return sub { ++$n }; # closes over this $n } my $c = make_counter(); $c->(); $c->(); # 1, 2 ``` ## List form and destructuring With parentheses, `my` supplies list context to the right-hand side and destructures the result: ```perl my ($sec, $min, $hour) = localtime; my ($head, @tail) = @list; # @tail absorbs the rest my ($x, $y) = ($y, $x); # swap via list assignment ``` Use [`undef`](undef) as a placeholder to skip a position: ```perl my (undef, $min, $hour) = localtime; # discard seconds ``` Without parentheses, `my $foo` is a single-variable declaration and the comma operator applies to whatever follows: ```perl my $foo, $bar = 1; # WRONG: declares $foo only; # $bar is the package variable my ($foo, $bar) = (0, 1); # Right. ``` ## Context traps `my` does not change how the right-hand side is evaluated — it only modifies the variable on the left. A scalar `my $foo` imposes scalar context; a parenthesised `my (...)` imposes list context: ```perl my $line = <$fh>; # scalar context: one line my ($line) = <$fh>; # list context: first of a list my @lines = <$fh>; # list context: all remaining lines ``` The classic mistake is writing `my ($foo) = <$fh>` when a single line was wanted — the parentheses turn on list context and the filehandle returns a one-element list; the value happens to be the first line, but the surrounding context is wrong for anything that follows. ## `my` vs `local` vs `our` vs `state` Four declarations, four different meanings: - [`my`](my) — introduces a **new lexical** variable. Not visible to called code. Fresh storage each entry. - [`local`](local) — does **not** declare anything. It saves the current value of an **existing package** variable and restores it when the enclosing scope exits. Visible to called code through dynamic scope. Use it for the handful of magical globals (`$_`, `$/`, `$\`, `$,`, `$|`, `%ENV`, ...) that cannot be lexicalised. - [`our`](our) — declares a **lexical alias** for a package (global) variable. The storage lives in the package's symbol table; `our` just lets you refer to it without the package prefix for the rest of the lexical scope. Satisfies `use strict 'vars'`. - [`state`](state) — like `my` in visibility, but the storage **persists** across re-entries to the scope. Initialisation runs once; subsequent entries leave the value alone. ```perl package Counter; our $total = 0; # package global; $Counter::total my $cache; # lexical; invisible outside this file state $calls = 0; # lexical; keeps its value across calls sub tick { local $\ = "\n"; # temporarily override output separator ++$calls; print ++$total; } ``` Critical point: `my $var` does **not** mask a package variable with the same name. The package variable remains accessible through its fully qualified form while the lexical is in scope: ```perl package main; our $x = 10; my $x = 20; print "$x and $::x\n"; # "20 and 10\n" ``` ## TYPE and attributes Both forms are part of the language but their semantics are still evolving (upstream wording). - **TYPE** — a bareword class name, a constant declared via `use constant`, or [`__PACKAGE__`](__PACKAGE__). Historically bound to the `fields` pragma; for ordinary use it serves as a hint and does not enforce a type at runtime. ```perl my Foo $obj = Foo->new; ``` - **ATTRS** — a colon-introduced attribute list handled by the `attributes` pragma (and `Attribute::Handlers` since 5.8.0). ```perl my $x : shared; my @buf : Locked; ``` See L upstream for the authoritative wording. ## Declaration is not yet in scope on its own RHS The newly declared variable is not visible until **after** the declaring statement finishes. That makes this idiom well-defined: ```perl my $x = $x; # new $x initialised from the old $x ``` and this condition dependent on a pre-existing outer `$x`: ```perl my $x = 123 and $x == 123; # false unless the old $x was 123 ``` Within a single statement, any further mentions of the name refer to the pre-declaration binding (or raise a `strict 'vars'` error if no such binding exists): ```perl our $x = 2; foo($x, my $x = $x + 1, $x); # foo() receives (2, 3, 2) ``` ## Examples Typical subroutine entry — name the arguments: ```perl sub distance { my ($x1, $y1, $x2, $y2) = @_; return sqrt( ($x2-$x1)**2 + ($y2-$y1)**2 ); } ``` Loop-local index with `for my`: ```perl for my $i (1 .. 10) { # $i is fresh each iteration; invisible after the loop } ``` File-scoped private state — the variable exists for the life of the interpreter but is unreachable from outside this file: ```perl my $cache = {}; sub lookup { $cache->{ $_[0] } //= _compute($_[0]) } ``` Private subroutine via a lexical coderef: ```perl my $helper = sub { ... }; $helper->($x); ``` Shadowing warning — redeclaring in the same scope emits a `shadow`-category warning under `use warnings`: ```perl use warnings 'shadow'; my $x = 1; my $x = 2; # warning: "my" variable $x masks ... ``` ## Edge cases - **Only alphanumeric identifiers.** Magical built-ins such as `$/`, `$_`, `$\`, `%ENV`, `@ARGV` cannot be lexicalised. Use [`local`](local) to scope them dynamically. - **No package qualification.** `my $Foo::bar` is a syntax error: `my` variables are not package-owned and cannot carry a `::` qualifier. - **Missing parentheses around a list.** `my $a, $b` declares only `$a`; `$b` is the package variable. Always parenthesise two or more names. - **List-context surprise.** `my ($line) = <$fh>` forces list context on the read; the RHS is a one-element list, not a scalar. Drop the parentheses if you want scalar semantics. - **`foreach` without `my`.** `for $i (...)` localises `$i` dynamically in the manner of `local`. Prefer `for my $i (...)` to confine the index lexically. - **Shadowing in loops.** A `my` inside a loop body declares a fresh variable every iteration. If that is unwanted (e.g. a counter that should survive iterations), declare it outside the loop or use [`state`](state). - **Closure capture.** A closure over a `my` variable keeps that particular instance alive. Different calls to an enclosing sub produce independent closures over independent variables. - **`use strict 'vars'` interaction.** `my` satisfies strict-vars within its scope; variables without a declaration must be [`our`](our), fully qualified, or predeclared with `use vars`. - **Compile-time vs run-time.** The name binding happens at compile time; the initialiser runs at run time, and re-runs on each scope entry. Expensive initialisers inside hot loops pay that cost every iteration. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`our`](our) — lexical alias for a package variable; satisfies `strict 'vars'` without creating new storage - [`local`](local) — dynamically scoped save/restore of an existing package variable; the tool for magical globals - [`state`](state) — lexical like `my`, but storage persists across scope re-entries - [`undef`](undef) — placeholder in a parenthesised `my` list, and the initial value of an uninitialised scalar - `use strict` — makes `my` / `our` / fully-qualified names mandatory, catching accidental globals - `attributes` — pragma that interprets the `: ATTRS` portion of a `my` declaration