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#
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
LISTin 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. Underuse 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:
my @back = reverse "abc", "def"; # ("def", "abc")
my $back = reverse "abc", "def"; # "fedcba"
Used with no arguments in scalar context, reverse reverses $_.
Used with no arguments in list context, reverse returns the empty
list — not a reversed $_. print reverse; produces no output.
Global state it touches#
Reads $_ when called with no arguments in scalar context. That is
the only global it touches. It does not modify $_; it returns the
reversed string.
Examples#
Reverse a list. The elements themselves are unchanged:
my @a = (1, 2, 3, 4, 5);
my @r = reverse @a; # (5, 4, 3, 2, 1)
Reverse a string. Force scalar context with scalar when the
surrounding expression would otherwise be list:
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:
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:
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:
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:
my $word = "stressed";
my $rev = scalar reverse $word; # "desserts"
Edge cases#
The #1 trap: context.
my $s = reverse @arrdoes 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 $strreturns($str)— a one-element list containing$strunchanged. There is nothing to reorder. To reverse the characters, force scalar context:my $r = reverse $strormy @r = (scalar reverse $str).Hash invert loses data on duplicate values.
reverse %hwalks 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: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.
reversewith no args returns()in list context.$_is only consulted in scalar context.print reverse;prints nothing;print scalar reverse;prints the reverse of$_.Character-wise, not byte-wise. For wide-character strings,
reversereverses characters, not bytes. A:utf8string 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 @aon a non-magical or well-behaved tied array preserves non-existent elements in their reversed positions; a sparse array stays sparse.reverse sortis not the same assort { $b cmp $a }. Both give descending order for a stable default compare, butreverse sortdoes 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— pair withreversefor descending order, or swap$a/$bin the comparator to avoid the second passpop— remove from the end of an array when you just want the last element, not the whole list reversedshift— remove from the front; combined with areversed copy you get stack-like access to the original tailsplit— produce a list of characters (with//) or fields that you can thenreversejoin— the natural partner when you reverse a list of strings and want a single string back$_— the default target whenreverseis called with no arguments in scalar context