String Interpolation
SUBROUTINE INTERPOLATION IN PERL STRINGSThis page shows how to call subroutines inside double-quoted strings in Perl. You will learn the two syntax patterns that handle single values and lists, plus a few practical examples you can paste into your own scripts.
Part 1: THE PROBLEM
You might think this would work:But nope - that just prints the literal text "get_name()".say "Hello, get_name()!";
Perl interpolates variables like $name and @items, but it doesn't automatically recognize bare subroutine calls. We need to wrap them in a special syntax.
Part 2: SCALAR CONTEXT WITH \${\()}
When you want to interpolate a subroutine that returns a single value (scalar context), use the ${\()} construct:What's happening here? Let's break it down:sub get_greeting { return "Welcome to Perl"; } say "Hello! ${\(get_greeting())}"; # Output: Hello! Welcome to Perl
The backslash creates a reference, and ${ } dereferences it right back. It's a round trip that tricks Perl into evaluating your subroutine inside the string.${ ... } - Dereference a scalar reference \( ... ) - Create a reference to the result get_greeting() - Your subroutine call
Part 3: LIST CONTEXT WITH @{[]}
When your subroutine returns a list, or you want to preserve list context, use @{[]}:Want them comma-separated? Combine with join:sub get_top_cities { return ("Tokyo", "Paris", "New York"); } say "Cities: @{[get_top_cities()]}"; # Output: Cities: Tokyo Paris New York
The @{[]} construct works similarly:say "Cities: @{[join(', ', get_top_cities())]}"; # Output: Cities: Tokyo, Paris, New York
The square brackets capture the list into an arrayref, then @{ } expands it back into the string with spaces between elements (or whatever $" is set to).@{ ... } - Dereference an array reference [ ... ] - Create an anonymous array reference
Part 4: ANONYMOUS SUBROUTINES
You can even define and call anonymous subs inline:Or with list context:my $multiplier = 5; say "Result: ${\(sub { return 6 * $multiplier }->())}"; # Output: Result: 30
This is particularly handy for quick transformations without defining a named subroutine.say "Doubled: @{[map { $_ * 2 } (1, 2, 3)]}"; # Output: Doubled: 2 4 6
Part 5: PRACTICAL EXAMPLES
Timestamps in log messages:Dynamic pluralization:sub timestamp { my @t = localtime; return sprintf("%04d-%02d-%02d %02d:%02d:%02d", $t[5]+1900, $t[4]+1, $t[3], $t[2], $t[1], $t[0]); } say "[${\(timestamp())}] Application started";
Conditional content:sub pluralize { my ($count, $word) = @_; return $count == 1 ? "$count $word" : "$count ${word}s"; } my $files = 7; say "Processing ${\(pluralize($files, 'file'))}..."; # Output: Processing 7 files...
my $user = "Alice"; my $is_admin = 1; say "Welcome, $user${\($is_admin ? ' (Administrator)' : '')}!"; # Output: Welcome, Alice (Administrator)!
Part 6: MEMORY AID
Here's a simple way to remember which to use:Both use the same principle: create a reference, then immediately dereference it inside the string.${\()} - Dollar sign for Scalar (single value) @{[]} - At sign for Array (list of values)
CONCLUSION
String interpolation with subroutines might look a bit cryptic at first, but once you understand the reference and dereference dance, it becomes second nature.
These constructs let you build dynamic strings without awkward concatenation or temporary variables. Clean, expressive, and very Perlish.${\(scalar_sub())} - for single values @{[list_sub()]} - for lists
perl.gg