Perl::...holders(3pm)

πŸ’– Perl::Critic::Policy::Miscellanea::TextDomainPlaceholders ✨

okay bestie so this is a page from the Perl::...holders(3pm) manual β€” manual name's Perl::Critic::Policy::Miscellanea::TextDomainPlaceholders, and it's giving "your placeholder args are messy and I'm about to tell you". let's get into it 🫢


🌸 NAME 🌸

Perl::Critic::Policy::Miscellanea::TextDomainPlaceholders β€” checks the placeholder names in Locale::TextDomain calls, no cap. πŸ’…


πŸ¦‹ DESCRIPTION πŸ¦‹

so this policy is part of the Perl::Critic::Pulp add-on, it's one of the little guys in there. what it does: it checks the placeholder arguments in your format strings for these functions from Locale::TextDomain:

__x __nx __xn __px __npx

if you call one of those and a key is missing from the args, or an arg is never used by the format β€” yeah, that gets reported. 🚨

print __x('Searching for {data}',  # bad
          datum => 123);

print __nx('Read one file',
           'Read {num} files',     # bad
           $n,
           count => 123);

this is normally a mistake, which is exactly why this policy hangs out under the "bugs" theme (peep "POLICY THEMES" in Perl::Critic for more). and the reason it's sneaky: as of Locale::TextDomain version 1.16, a placeholder with no matching arg just... goes through unexpanded, and any extra args just get ignored. so the error is lowkey invisible until you look. πŸ’€

now, the way Locale::TextDomain parses the format string, literally anything between { } can be a key. but for this policy's purposes, only symbols (alphanumeric plus "_") count as a key. and honestly? that's almost certainly what you want anyway, plus it means you can drop literal braces into a format string without this policy screaming at you every single time. πŸŽ€ (symbol characters follow Perl's "\w", so non-ASCII is supported β€” though the Gettext manual, in node "Charset conversion", recommends message-IDs be ASCII-only. noted.)

🧚 Partial Checks 🧚

if the format string isn't a literal, then it could use any args β€” so everything counts as used, chill.

# ok, 'datum' might be used
__x($my_format, datum => 123);

but the literal portions of the format still get checked, bestie.

# bad, 'foo' not present in args
__x("{foo} $bar", datum => 123);

and the flip side: if the args have non-literals in them, they could be anything, so everything in the format string is considered present.

# ok, $something might be 'world'
__x('hello {world}', $something => 123);

but again β€” if some args are literals, they can totally be checked. ✨

# bad, 'blah' is not used
__x('hello {world}', $something => 123, blah => 456);

and if there's non-literals in both the format and the args? nothing gets checked, because fr fr it could all match up just fine at runtime. 🫠

πŸ‘‘ "__nx" Count Argument πŸ‘‘

a missing count argument to "__nx", "__xn" and "__npx" is sometimes caught by this policy. like:

print __nx('Read one file',
           'Read {numfiles} files',
           numfiles => $numfiles);   # bad

if the count argument looks like a key, it gets reported as a probable mistake. now listen β€” this isn't the main aim of this policy, it's just here because otherwise literally no violations would get reported at all. 😭 the reasoning: the next argument would be the key, and normally being an expression, it'd be assumed to fulfill the format strings at runtime.


🌈 SEE ALSO 🌈

  • Perl::Critic::Pulp
  • Perl::Critic
  • Locale::TextDomain
  • Perl::Critic::Policy::Miscellanea::TextDomainUnused

πŸ“ HOME PAGE πŸ“

<http://user42.tuxfamily.org/perl-critic-pulp/index.html>


Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2019, 2021 Kevin Ryde

Perl-Critic-Pulp is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.

Perl-Critic-Pulp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with Perl-Critic-Pulp. If not, see <http://www.gnu.org/licenses/>.

also pls note: no warranty, ok? the license literally said so, I'm just relaying the message πŸ’…

and that's the whole thing, bestie! signed off from perl v5.40.1 on 2025-10-21 β€” this manual page really said "here for a good time and a thorough placeholder check", periodt. πŸŽ€βœ¨

πŸ“¦ where this page comes from