develooper Front page | perl.perl5.porters | Postings from July 2016

Re: Correct way to access %^H from XS?

Thread Previous | Thread Next
From:
Zefram
Date:
July 11, 2016 21:03
Subject:
Re: Correct way to access %^H from XS?
Message ID:
20160711210331.GO1170@fysh.org
Maxwell Carey wrote:
>I'm trying to access %^H from XS code.

You're confused about which %^H you want to access.  For some purposes
one needs to access the current %^H at compile time.  For others one
needs to see what %^H contained when the currently-executing code was
being compiled.  For your case:

>$ perl -MExtUtils::testlib -e'use Foo; Foo::print_key; no Foo;
>Foo::print_key; use Foo; Foo::print_key'

Foo::print_key() executes at runtime, and you want to see what %^H
contained during compilation of the call, *not* the current %^H at the
time of the call.

Your first XS code:
>        HE* const he = hv_fetch_ent(GvHV(PL_hintgv), key_sv, FALSE, 0U);

is reading the current %^H, which is not what you want.

Your second and third versions:

>        SV *const bar = cophh_fetch_pvs(PL_curcop->cop_hints_hash,
>"Foo/bar", 0);
...
>    SV *const val = cophh_fetch_pvn(PL_curcop->cop_hints_hash, key,
>strlen(key), 0, 0);

both look at the historical %^H via the cop that's in effect at the
point of the call, which is what you want.  Both of these work.

>and all seem to fail for $^H{key} = 0.

That's because you've explicitly coded both of the working ones to treat
zero the same as undef.  For example,

>        if (SvOK(bar) && SvIV_nomg(bar)) {
>            printf("Value: %d\n", SvIV(bar));
>        }
>        else {
>            printf("Value: -1\n");
>        }

If bar is a defined integer SV with the value zero, you go into the
second branch and show -1 instead of 0.

-zefram

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About