--- name: reverse signature: 'reverse LIST' since: 5.0 status: documented categories: ["SCALARs and strings", "Lists"] --- ```{index} single: reverse; Perl built-in ``` *[SCALARs and strings](../perlfunc-by-category) · [Lists](../perlfunc-by-category)* # reverse Reverse a list — or, in scalar context, reverse the characters of a string. `reverse` is two operators wearing the same name. Context decides which one you get. In list context it returns `LIST` with its elements in the opposite order; element values are untouched. In scalar context it concatenates `LIST` into a single string and returns that string with its **characters** reversed. The common mistake of writing `my $s = reverse $str` and expecting a reversed list (or writing `print reverse $str` and expecting a reversed string) is the single biggest trap this function has — see *Edge cases*. ## Synopsis ```perl my @r = reverse @arr # list context: elements reversed my $s = reverse $str # scalar context: characters reversed my %inv = reverse %h # hash invert (value → key) reverse # in scalar context, reverses $_ ``` ## What you get back Context-dependent. The operator inspects the context of its caller and branches: - **List context** → a new list with the elements of `LIST` in reverse order. Element values are not stringified, not modified, not copied at the character level. A list of refs stays a list of the same refs. - **Scalar context** → a single string: the concatenation of the stringified elements of `LIST`, with all characters in reverse order. Under `use utf8` / wide strings, reversal is character-wise, not byte-wise. This means the *same* call site returns radically different shapes depending on how you use it: ```perl my @back = reverse "abc", "def"; # ("def", "abc") my $back = reverse "abc", "def"; # "fedcba" ``` Used with no arguments in scalar context, `reverse` reverses [`$_`](../perlvar). Used with no arguments in list context, `reverse` returns the empty list — **not** a reversed [`$_`](../perlvar). `print reverse;` produces no output. ## Global state it touches Reads [`$_`](../perlvar) when called with no arguments in scalar context. That is the only global it touches. It does not modify [`$_`](../perlvar); it returns the reversed string. ## Examples Reverse a list. The elements themselves are unchanged: ```perl my @a = (1, 2, 3, 4, 5); my @r = reverse @a; # (5, 4, 3, 2, 1) ``` Reverse a string. Force scalar context with [`scalar`](scalar) when the surrounding expression would otherwise be list: ```perl my $s = reverse "Hello, world"; # "dlrow ,olleH" print scalar reverse "Hello"; # "olleH" ``` Iterate an array backward without building a second array. `reverse` in the loop header is a list-context call; Perl consumes the reversed list lazily from the loop machinery: ```perl my @stack = ("first", "second", "third"); for my $elem (reverse @stack) { print "$elem\n"; # third / second / first } ``` Descending sort. `reverse sort` is the idiom when your comparison is ascending and you want the opposite. For anything more complex than default string compare, swap the operands in the comparator instead: ```perl my @asc = sort { $a <=> $b } @nums; my @desc = reverse sort { $a <=> $b } @nums; # works my @desc2 = sort { $b <=> $a } @nums; # preferred ``` Invert a hash. Values become keys, keys become values: ```perl my %by_name = (alice => 1, bob => 2, carol => 3); my %by_id = reverse %by_name; # (1 => "alice", ...) print $by_id{2}; # "bob" ``` The `"dlrow ,olleH"` trick — using `reverse` in scalar context as a one-shot character flip on a string variable: ```perl my $word = "stressed"; my $rev = scalar reverse $word; # "desserts" ``` ## Edge cases - **The #1 trap: context.** `my $s = reverse @arr` does **not** give you a reversed array; it gives you the reversed *string* formed by concatenating the array's elements and flipping every character. If you want a reversed array stored via a scalar, use a reference: `my $ref = [ reverse @arr ]`. - **Single scalar, wrong context.** `my @r = reverse $str` returns `($str)` — a one-element list containing `$str` unchanged. There is nothing to reorder. To reverse the characters, force scalar context: `my $r = reverse $str` or `my @r = (scalar reverse $str)`. - **Hash invert loses data on duplicate values.** `reverse %h` walks the key/value pairs as a flat list and rebuilds a hash. If two keys share a value, one of them wins and the other is silently dropped; which one wins is not defined. Check for uniqueness first if it matters: ```perl my %seen; $seen{$_}++ for values %h; die "non-unique values" if grep { $_ > 1 } values %seen; my %inv = reverse %h; ``` - **No arguments in list context does nothing useful.** `reverse` with no args returns `()` in list context. [`$_`](../perlvar) is only consulted in scalar context. `print reverse;` prints nothing; `print scalar reverse;` prints the reverse of [`$_`](../perlvar). - **Character-wise, not byte-wise.** For wide-character strings, `reverse` reverses characters, not bytes. A `:utf8` string of three code points stays three code points after reversal, regardless of their byte widths. Reversing a raw byte string with multi-byte characters you never decoded will corrupt it — decode first. - **Self-assignment preserves holes.** `@a = reverse @a` on a non-magical or well-behaved tied array preserves non-existent elements in their reversed positions; a sparse array stays sparse. - **`reverse sort` is not the same as `sort { $b cmp $a }`.** Both give descending order for a stable default compare, but `reverse sort` does two passes over the data and is measurably slower on large lists. Prefer swapping the comparator operands. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`sort`](sort) — pair with `reverse` for descending order, or swap `$a`/`$b` in the comparator to avoid the second pass - [`pop`](pop) — remove from the end of an array when you just want the last element, not the whole list reversed - [`shift`](shift) — remove from the front; combined with a `reverse`d copy you get stack-like access to the original tail - [`split`](split) — produce a list of characters (with `//`) or fields that you can then `reverse` - [`join`](join) — the natural partner when you reverse a list of strings and want a single string back - [`$_`](../perlvar) — the default target when `reverse` is called with no arguments in scalar context