Is the truthiness of a dualvar always that of its string part?

Yes, at least so far. The SvTRUE_common macro is usually used to decide where an SV is "true" in a boolean context. Here's how it is defined in sv.h in the perl 5.26.1 source:

#define SvTRUE_common(sv,fallback) (            \
      !SvOK(sv)                     \
    ? 0                     \
    : SvPOK(sv)                     \
    ? SvPVXtrue(sv)                 \
    : (SvFLAGS(sv) & (SVf_IOK|SVf_NOK))         \
    ? (   (SvIOK(sv) && SvIVX(sv) != 0)     \
       || (SvNOK(sv) && SvNVX(sv) != 0.0))      \
    : (fallback))

After the scalar passes the SvOK test (whether it is defined), the next check is SvPOK -- whether the scalar has a valid internal string representation. Dualvars always pass this check, so the boolean test of a dualvar is whether its string representation is true (SvPVXtrue(...)).

The code is different in perl 5.6.2

I32
Perl_sv_true(pTHX_ register SV *sv)
{
    if (!sv)
        return 0;
    if (SvPOK(sv)) {
        register XPV* tXpv;
        if ((tXpv = (XPV*)SvANY(sv)) &&
                (tXpv->xpv_cur > 1 ||
                (tXpv->xpv_cur && *tXpv->xpv_pv != '0')))
            return 1;
        else
            return 0;
    }
    else {
        ...

but the logic is the same -- check SvPOK first and then return whether the string representation is not empty and not equal to "0".

I would think future generations of Perl developers would be wary of changing this long-standing logic.


Question: Is this guaranteed behaviour?

This boils down to how a scalar is tested in the Boolean context, as string or numeric?

In Perl the documentation is the closest thing to a standard. So if there is no statement in docs then the formal answer must be: No, it is not "guaranteed behaviour".

Since the docs come tantalizingly close a few times, talking about that context and conversions, and yet specifically do not spell out which test is done I'd say that this must indeed be taken as an implementation detail. You cannot "rely" on it.

If strict reliability is needed one solution is a simple class that ensures to test what you need.

In more practical terms, it appears that in if ($v) it is the string part that is tested, and if it's not there then a numeric test goes (without the actual conversion as the docs say). As you ask about variables that have been set as dualvar then for those it's going to be the string test.