╔╗ ╔═╗╔╗ ╦ ╦╔═╗╔═╗╦═╗╔╦╗ ╠╩╗╠═╣╠╩╗╚╦╝║ ╠═╣╠╦╝ ║ ╚═╝╩ ╩╚═╝ ╩ ╚═╝╩ ╩╩╚═ ╩ ╔═╗╔═╗╔═╗╦═╗╔═╗╔╦╗╔═╗╦═╗ ║ ║╠═╝║╣ ╠╦╝╠═╣ ║ ║ ║╠╦╝ ╚═╝╩ ╚═╝╩╚═╩ ╩ ╩ ╚═╝╩╚═ ============================================================================ 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 ============================================================================ japh.codes