ADR-002: Multi-method signatures for CAN and DOES predicates
Status
Proposed
Context
The current _CLASSCAN, _INSTANCECAN, _INVOCANTCAN, _CLASSDOES, and _INSTANCEDOES predicates accept exactly one method or role name ($$ prototype).
In practice, callers often need to verify that an invocant satisfies multiple capabilities at once (e.g. "provides both connect and disconnect") or fulfils several roles simultaneously. Today this requires chaining multiple calls:
_INSTANCECAN($obj, 'connect') and _INSTANCECAN($obj, 'disconnect')
This is verbose and evaluates the blessed/class check repeatedly.
Decision
Deferred. Introduce multi-method variants once a concrete consumer demonstrates the need. The design space includes:
- Signature change
-
_INSTANCECAN($obj, @methods)-- breaks the$$prototype. Prototypes cannot express$@, so the function would need to drop its prototype or use a different calling convention. - Semantic: AND vs OR
-
Multiple arguments most naturally mean "provides all of these" (AND). An OR semantic ("provides at least one") is a different use case and would warrant a separate function name to avoid ambiguity.
- XS implications
-
A variadic XS implementation must loop over the method list in C, calling
->canor->DOESfor each. The early-exit on first failure makes this efficient, but the stack handling differs from the current fixed-arity pattern. - Interaction with Assert (ADR-003)
-
An assertion variant that reports which method is missing benefits from knowing the full list up front rather than failing on the first chained call.
Consequences
No action required now; the
$$variants are sufficient for the initial release.When a consumer emerges, the multi-method variant should be added as a new function name (e.g.
_INSTANCECAN_ALL) rather than changing the existing$$signature, preserving backwards compatibility.The same pattern applies to
_CLASSDOES/_INSTANCEDOESfor verifying multiple roles simultaneously.