control-flow intermediate

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:

  • given takes a scalar expression and sets it as the topic variable inside the block.
  • when compares the topic variable to a match condition using smart matching (~~), which is context-sensitive and can match scalars, regex, array membership, and more.
  • The when branch whose condition matches first is executed; subsequent when blocks are skipped like a typical switch.
  • You can use default as a catch-all branch if none of the when conditions match.

Important Perl Concepts

  • Smart matching with ~~: The when condition uses smart matching introduced in Perl 5.10. Its behavior depends on the left and right operand types.
  • Topic variable $_: Inside given, the evaluated expression is placed in $_ for use in when blocks.
  • TMTOWTDI: Perl allows multiple ways to do the same thing, but given-when can 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-when is experimental in Perl 5.10 to 5.24 and may emit warnings. It was deprecated in Perl 5.18, but still works under feature 'switch'. For production use, consider other idioms like chained if-elsif or Dispatch::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, when does not fall through by default—you do not need explicit breaks.
  • Context awareness: given sets $_, 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

Tip: edit code and use “Run (Browser)”. Server runs always execute the published, verified snippet.
STDOUT
Fruit is pear
STDERR
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.

Was this helpful?

Related Questions