On Sun, Dec 12, 2004 at 01:18:10AM +0000 Sisyphus wrote:

> How does one set the value from perl-space and from C-space (ie - 2 
> separate questions) so that 'sv==&PL_sv_yes' returns true ?

In general, this can't be done reliably.

> I've been testing for that condition as regards the third argument that 
> my 'use overload' xsubs receive - and it has been working flawlessly, 
> Sometimes the condition is true, sometimes not. The condition has always 
> tested as I want and expect, and the response has always been 
> appropriate to the condition. But all my attempts to write code such 
> that 'sv==&PL_sv_yes' returns true have failed.

The problem is that you are doing pointer comparisons. So for the above
condition to hold true, it would require a prior

    sv = &PL_sv_yes;

> Here is what I tried:
> 
> use warnings;
> 
> use Inline C => Config =>
>     BUILD_NOISY => 1;
> 
> use Inline C => <<'EOC';
> 
> void set_TRUE(SV * a) {
>  sv_setsv(a, &PL_sv_yes);

This line does not do the required

    a = &PL_sv_yes;

Instead, it does more. Internally it calls Perl_sv_setsv_flags. This
function will look at both the destination and the source SV. The
destination SV will be upgraded accordingly and then it copies certain
fields from the source SV (&PL_sv_yes in this case). The result is that
'a' will be the similar to PL_sv_yes but 'a' will not be a pointer to
PL_sv_yes.

PL_sv_yes looks like this:

    SV = PVNV(0x814d6b8) at 0x814c60c
      REFCNT = 2147483647
      FLAGS = (NOK,POK,READONLY,pNOK,pPOK)
      IV = 0
      NV = 1
      PV = 0x814da80 "1"\0
      CUR = 1
      LEN = 2

After doing 'sv_setsv(a, &PL_sv_yes)' a is:

    SV = PVNV(0x827e050) at 0x8165848
      REFCNT = 1
      FLAGS = (PADBUSY,PADMY,NOK,POK,pNOK,pPOK)
      IV = 0
      NV = 1
      PV = 0x82928f8 "1"\0
      CUR = 1
      LEN = 2

Note that PVNV(0x814d6b8) != PVNV(0x827e050) and therefore &PL_sv_yes != a.

>  if(a == &PL_sv_yes)
>   printf("Set to &PL_sv_yes\n"); // Never happens
> }
> 
> void is_TRUE(SV * a) {
>  if(SvTRUE(a)) printf("true : ");
>  else printf("NOT true : ");
> 
>  if(a == &PL_sv_yes) printf("true\n");
>  else printf("NOT true\n");
> }
> 
> EOC
> 
> $x = '';
> set_TRUE($x);
> 
> print $x, "\n";
> 
> for(TRUE, $x, 1, '1', '', 0, '0', undef) {is_TRUE($_)}
> 
> __END__
> 
> prints:
> 1
> true : NOT true
> true : NOT true
> true : NOT true
> NOT true : NOT true
> NOT true : NOT true
> NOT true : NOT true
> NOT true : NOT true
> 
> I could perhaps use SvTRUE() to test that "third argument", but for the 
> moment what's really puzzling me is how my current method of testing 
> ever worked to begin with.

Where did it work? Further above you said that the comparison 'a ==
&PL_sv_yes' was never true.

Tassilo
-- 
$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval

Reply via email to