How to use the given-when switch statement in Perl?
Question
How to use the given-when switch statement in Perl?
The given-when construct was introduced in Perl 5.10 as an experimental "switch" statement to provide a more expressive and concise way to perform multi-way branching, similar to switch/case statements in other languages. It allows you to evaluate an expression once with given and then compare it against multiple when blocks.
Here’s a breakdown of how given-when works:
giventakes a scalar expression and sets it as the topic variable inside the block.whencompares the topic variable to a match condition using smart matching (~~), which is context-sensitive and can match scalars, regex, array membership, and more.- The
whenbranch whose condition matches first is executed; subsequentwhenblocks are skipped like a typical switch. - You can use
defaultas a catch-all branch if none of thewhenconditions match.
Important Perl Concepts
- Smart matching with
~~: Thewhencondition uses smart matching introduced in Perl 5.10. Its behavior depends on the left and right operand types. - Topic variable
$_: Insidegiven, the evaluated expression is placed in$_for use inwhenblocks. - TMTOWTDI: Perl allows multiple ways to do the same thing, but
given-whencan make complex chained if-else conditions neater. - Experimental warnings: The feature is experimental in Perl 5.10 through 5.24. You should
use feature 'switch'to enable it.
Syntax and Runnable Example
use strict;
use warnings;
use feature 'switch'; # enables given-when in Perl 5.10+
my $value = 'pear';
given ($value) {
when ('apple') { print "Fruit is apple\n"; }
when ('banana') { print "Fruit is banana\n"; }
when ('orange') { print "Fruit is orange\n"; }
when ('pear') { print "Fruit is pear\n"; }
default { print "Unknown fruit\n"; }
}
# Output:
# Fruit is pear
Explanation
In this example, given($value) sets $_ to 'pear'. Each when compares $_ against its condition using smart matching. The block corresponding to the first matching when executes, so Fruit is pear prints.
More Complex Match Examples
Smart matching lets you do more than simple equality:
use strict;
use warnings;
use feature 'switch';
my $var = 42;
given($var) {
when ([1..10]) { print "Between 1 and 10\n" }
when ($_ % 2 == 0) { print "An even number\n" }
default { print "Something else\n" }
}
Here, when([1..10]) tests if $_ is contained in the array (range 1..10). Next when uses a scalar condition ($_ % 2 == 0) which works as a boolean test.
Common Pitfalls
- Experimental feature:
given-whenis experimental in Perl 5.10 to 5.24 and may emit warnings. It was deprecated in Perl 5.18, but still works underfeature 'switch'. For production use, consider other idioms like chained if-elsif orDispatch::Table. - Smart match anomalies: The smart match operator
~~has had changes and some unpredictable behavior especially when comparing references or complex data types. - Break behavior: Unlike switch in some languages,
whendoes not fall through by default—you do not need explicit breaks. - Context awareness:
givensets$_, so be cautious if you rely on$_outside, as it changes your script’s global topic temporarily.
Summary
The given-when statement offers a more readable, switch-style control flow for multiple conditional branches, leveraging Perl’s smart match capabilities. Enable it with use feature 'switch' in Perl 5.10+. While powerful, be mindful of its experimental status and potential quirks. For simple matching or when you want safer syntax, traditional if-elsif chains often suffice, but given-when shines when you want expressive and concise branch handling.
Verified Code
Executed in a sandbox to capture real output. • v5.34.1 • 5ms
Fruit is pear
given is experimental at - line 7.
when is experimental at - line 8.
when is experimental at - line 9.
when is experimental at - line 10.
when is experimental at - line 11.