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

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

Thread Previous | Thread Next
From:
Maxwell Carey
Date:
July 11, 2016 21:41
Subject:
Re: Correct way to access %^H from XS?
Message ID:
CADLEpY7LH7BZPsCRR5LwNPC8KJJfC6PNcmCJgLkiX0Cuq1qTGA@mail.gmail.com
On Mon, Jul 11, 2016 at 3:03 PM, Zefram <zefram@fysh.org> wrote:

> 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.
>

Aha! I knew I was missing something, great explanation.


>
> 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.
>

The cophh* functions have been available since 5.13.7, but they're still
listed as experimental in the 5.24.0 docs. How likely are they to change or
go away?


>
> >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.
>

*facepalm* I can't believe I missed that. re::engine::RE2 and
re::engine::TRE both have snippets like this that call SvIV_nomg() before
SvIV(). Is there any reason I can't just do the following?

 if (SvOK(bar))
    printf("Value: %d\n", SvIV(bar));


>
> -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