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