perl.gg / secret-operators

Babycart Operator

2025-12-30

You know how double-quoted strings interpolate variables?
my $name = "Alice"; print "Hello, $name!"; # Hello, Alice!
But what about expressions? Math? Function calls?
print "Sum: $x + $y"; # Sum: 5 + 3 (not 8!)
Enter the babycart operator:
@{[ ]}
Five characters that let you interpolate ANY expression in a string.

Part 1: THE TRICK

my $x = 5; my $y = 3; print "Sum: @{[ $x + $y ]}"; # Sum: 8
The expression inside @{[ ]} gets evaluated and interpolated.

Works with anything:

print "Time: @{[ scalar localtime ]}"; print "Random: @{[ int(rand(100)) ]}"; print "Upper: @{[ uc('hello') ]}";

Part 2: HOW IT WORKS

Break it down from the inside out:
@{[ EXPRESSION ]} [ EXPRESSION ] Anonymous array reference containing EXPRESSION @{ ... } Dereference that array reference
The expression is evaluated in list context, wrapped in an anonymous array, then immediately dereferenced for interpolation.

It's a weird little dance, but it works.

.--. |o_o | |:_/ | // \ \ (| | ) /'\_ _/`\ \___)=(___/

Part 3: WHY THE NAME

Look at the operator from the side:
@{[ ]}
The @ is a person pushing a shopping cart []. Inside the cart is your expression, going along for the ride.

It's called babycart because... there's a baby (your expression) riding in the cart. Perl naming conventions are weird.

Also called the "pram" operator in British Perl circles.

Part 4: MATH IN STRINGS

The classic use case - calculations inside strings:
my $price = 19.99; my $qty = 3; my $tax_rate = 0.13; print "Subtotal: @{[ $price * $qty ]}\n"; print "Tax: @{[ $price * $qty * $tax_rate ]}\n"; print "Total: @{[ $price * $qty * (1 + $tax_rate) ]}\n";
Output:
Subtotal: 59.97 Tax: 7.7961 Total: 67.7661
No temporary variables needed.

Part 5: FUNCTION CALLS

Call any function and interpolate the result:
print "PWD: @{[ `pwd` ]}"; print "Files: @{[ scalar(`ls | wc -l`) ]}"; print "Date: @{[ scalar localtime ]}"; print "Name: @{[ (getpwuid($<))[0] ]}";
Backticks, builtins, anything goes.

Part 6: COMPLEX EXPRESSIONS

You can go nuts:
my @nums = (1, 5, 3, 9, 2); print "Sorted: @{[ sort { $a <=> $b } @nums ]}\n"; print "Max: @{[ (sort { $b <=> $a } @nums)[0] ]}\n"; print "Sum: @{[ do { my $s; $s += $_ for @nums; $s } ]}\n";
Output:
Sorted: 1 2 3 5 9 Max: 9 Sum: 20
The do{} block lets you run multiple statements.

Part 7: CONDITIONALS

Ternary operators work great:
my $count = 0; print "You have @{[ $count || 'no' ]} items\n"; # You have no items $count = 5; print "You have @{[ $count == 1 ? 'item' : 'items' ]}\n"; # You have items
Dynamic pluralization:
print "Found @{[ $n ]} file@{[ $n == 1 ? '' : 's' ]}\n";

Part 8: HEREDOCS

Babycart shines in heredocs:
my $name = "Alice"; my $items = 5; my $total = 49.95; print <<"END"; Dear @{[ uc $name ]}, Your order of @{[ $items ]} items totaling \$@{[ sprintf "%.2f", $total ]} has been shipped. Sincerely, @{[ scalar localtime ]} END
Output:
Dear ALICE, Your order of 5 items totaling $49.95 has been shipped. Sincerely, Mon Jan 6 14:35:22 2025

Part 9: GOTCHAS

List context inside means arrays expand:
my @things = qw(one two three); print "Things: @{[ @things ]}"; # Things: one two three
If you want the count:
print "Count: @{[ scalar @things ]}"; # Count: 3
Or use the Venus operator:
print "Count: @{[ 0 + @things ]}"; # Count: 3

Part 10: VS CONCATENATION

You could always use concatenation:
print "Sum: " . ($x + $y) . "\n";
But babycart keeps everything in one string:
print "Sum: @{[ $x + $y ]}\n";
In heredocs and long strings, babycart is cleaner. In simple cases, concatenation might be more readable.

Your call. Both work.

Part 11: SPRINTF TRICK

For formatted numbers:
my $pi = 3.14159265359; print "Pi: @{[ sprintf '%.2f', $pi ]}\n"; # Pi: 3.14 my $bytes = 1536; print "Size: @{[ sprintf '%.1f KB', $bytes/1024 ]}\n"; # Size: 1.5 KB
Embedding sprintf in babycart is a common pattern.

Part 12: IN ONE-LINERS

Print line numbers with content:
perl -lne 'print "@{[$.]} $_"' file.txt
Pad numbers:
perl -le 'print "Num: @{[ sprintf q(%05d), $_ ]}" for 1..5'
Output:
Num: 00001 Num: 00002 Num: 00003 Num: 00004 Num: 00005
@{[ ]} || [ baby ] /______\ O O Your expression, along for the ride
perl.gg