# Comma operators Two operators, both spelled with a comma — one of them spelled «fat comma» with `=>`. They are syntactically the same in most positions but differ on the left-hand-side bareword rule. | Operator | Reads as | What it does | |------------|------------|-----------------------------------------------------------------------| | `,` | comma | list separator (in list ctx); discard-and-yield-right (in scalar ctx) | | `=>` | fat comma | same as `,`, plus auto-quotes a bareword on the left | ## In list context — building lists In list context the comma is the list-element separator: ```perl my @items = (1, 2, 3, 4); # 4-element list my @flat = (1, 2, (3, 4), 5); # (1,2,3,4,5) — lists flatten my @kv = (a => 1, b => 2); # 4-element list: a, 1, b, 2 my %h = (a => 1, b => 2); # hash from key-value pairs ``` Lists in Perl are *flat* — there is no nested-list value. A list embedded in another list disappears: its elements simply become elements of the outer list. To get nested structure you need references (see the [References tutorial](../../../tutorial/reference/index.md)): ```perl my @flat = (1, 2, (3, 4), 5); # (1,2,3,4,5) — 5 elements my @nested = (1, 2, [3, 4], 5); # (1, 2, ARRAYREF, 5) — 4 elements ``` ## In scalar context — comma is «discard, then return right» When a comma expression is *forced* into scalar context — by an assignment to a scalar, by `scalar(...)`, by being the condition of an `if` — it evaluates each operand left-to-right for side-effects, then yields the value of the rightmost operand: ```perl my $x = (1, 2, 3); # $x = 3 — but warn under # `use warnings`: "Useless use of # a constant in void context" # for 1 and 2 my $r = (do_a(), do_b(), final_value()); # runs all three, returns # the last value ``` This usage is rare in modern Perl — the C-style `for(init, init; cond; step, step)` idiom is the main place you encounter it (and even there, parens around the comma sub-expression are advisable). ## `=>` — the fat comma `=>` does the same thing as `,` *plus* it auto-quotes the identifier-shaped bareword on its left: ```perl my %h = ( name => "John", # 'name' auto-quoted age => 30, "key with spaces" => "...", # quote required for non-bareword ); # Equivalent without =>, requiring explicit quoting: my %h = ( 'name', "John", 'age', 30, 'key with spaces', '...', ); ``` The auto-quote applies only when the left side is **a syntactically valid bareword identifier** — letters, digits, underscores, starting with a letter or underscore. Other shapes are not auto-quoted: ```perl ( name => 1 ) # 'name' auto-quoted — fine ( "name" => 1 ) # already a string — fine ( $variable => 1 ) # $variable evaluated — fine ( 0+1 => 1 ) # numeric expression — fine ( -name => 1 ) # WRONG — looks like negative bareword; # parses as -('name') which is the # numeric negation of a string. Quote it. ( CONST => 1 ) # 'CONST' auto-quoted — does NOT call # the constant CONST! ( CONST() => 1 ) # explicit empty parens — calls CONST ``` The interaction with constants is the most common surprise — see also the [subscript](subscript.md) page on hash key autoquoting, which has the same pattern. ## Common idioms ```perl # Function arguments — the comma is just the argument separator some_function($arg1, $arg2, $arg3); # Hash construction — fat-comma communicates "this is a key" my %config = ( host => 'localhost', port => 8080, user => $ENV{USER}, ); # List literal — interchangeable my @months = (qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/); # Trailing comma — allowed and idiomatic for diff-friendly multi-line literals my @list = ( "first", "second", "third", # trailing comma is fine ); ``` The trailing comma is intentional: it lets you append, remove, or reorder list elements without touching surrounding lines, which shows up as cleaner diffs in version control. ## Precedence `,` and `=>` sit at row 20 — looser than assignment, tighter only than the word-form logicals (`and`/`or`/`not`/`xor`) and list operators in their right-side position. This is why a list of assignments works: ```perl my $a = 1, my $b = 2; # WRONG: parses as (my $a = 1), my $b = 2 # — comma at outer level, not list assignment. # $a is 1, $b is 2, but the warning is loud. my ($a, $b) = (1, 2); # the right way: list assignment ``` ## See also - [Assignment](assignment.md) — list assignment relies on the comma’s role in list context. - [Subscript](subscript.md) — `$h{name}` autoquoting, the parallel case to `name => ...`. - [`use constant`](../perlfunc/use.md) — the bareword/constant collision is the canonical fat-comma gotcha. - [Context](../perldata/context.md) — the list-vs-scalar story behind why `,` means two different things.