ADR-003: Params::Util::Assert -- assertion variants
Status
Proposed
Context
Params::Util predicates return the value on success or undef on failure. Callers that want to die on invalid input must wrap each check:
my $obj = _INSTANCE($val, 'Foo') or croak "expected a Foo";
This pattern is repetitive. An assertion module that dies directly would be more ergonomic and -- in XS -- more efficient, since it avoids the Perl-level conditional after the ->isa / ->can call.
Decision
Deferred. Ship Params::Util::Assert as a separate module within the same distribution once the interface stabilises. Key open questions:
- Error behaviour
-
croakvscarpvs throwing a structured exception object. Different consumers need different behaviour; a single hard-codedcroakdoes not serve them all. - Error message content
-
Minimally useful: the predicate name and the failing value's type. Maximally useful: parameter name, expected type, caller context. The richer the message, the more the interface must accept (extra arguments or configuration).
- Batch validation
-
Validating all parameters up front and collecting all failures (rather than dying on the first) is common in form/API validation. This fundamentally changes the control flow and may warrant a separate interface rather than extending the per-parameter assertion.
- XS integration
-
A direct
croakfrom XS avoids the return-check-croak round-trip. However, baking error-message formatting into C makes the module harder to extend. A possible middle ground: XS performs the check and calls a configurable Perl-level formatter only on the failure path. - Relationship to type systems
-
Type::Tiny, Specio, and Moose type constraints already provide assertion semantics.
Params::Util::Assertshould complement rather than compete -- it targets the lightweight, no-dependency niche where full type systems are overkill.
Consequences
No code ships until a concrete consumer clarifies the interface requirements.
When implemented, the module lives in lib/Params/Util/Assert.pm within the Params-Util distribution -- no separate dist, no runtime pollution for users who do not load it.
XS acceleration is desirable but must not lock in an error-reporting strategy that cannot be overridden from Perl.
The Assert interface should be designed with ADR-002 in mind: if multi-method
_CAN/_DOESvariants exist, the assertion should report which specific method or role was missing.