Nick Ing-Simmons wrote:

>Steve Hay <[EMAIL PROTECTED]> writes:
>  
>
>>Nick Ing-Simmons wrote:
>>    
>>
>>>Steve Hay <[EMAIL PROTECTED]> writes:
>>>      
>>>
>>>>How does an XSUB find out what package it is compiled into?
>>>>        
>>>>
>>>An XSUB isn't compiled into a package ;-)
>>>      
>>>
>
>Remember that.
>
:)

>>I spotted a couple of uses of $Package after sending my mail (e.g. in 
>>dl_*.xs files).  This works fine:
>>
>>void
>>foo(pkg="$Package")
>>   char *pkg;
>>PPCODE:
>>{
>>   warn("I'm compiled into %s\n", pkg);
>>}
>>
>>but unfortunately my usual foo() XSUB wasn't such a good idea this time...
>>
>>I really want the package name in a BOOT: section, so the above is no 
>>good :(
>>    
>>
>
>I don't see why BOOT: should be any different to any other XSUB.
>BOOT: is still in scope of a MODULE line.
>
>Snag is you don't have control over the arguments it gets so typemaps 
>are not much help.
>
>On the other hand the args you don't control XS side are useful...
>
>Remember that BOOT: is defining bootstrap method.
>So when you do 
>
>bootstrap Foo;  # i.e. Foo->bootstrap
>
>'Foo' is passed in ST(0) to BOOT:
>
>And XSLoader('Foo') 
>
>Defines then calls Foo->bootstrap.
>
>So 
>
>BOOT:
> {
>  warn("Booting package %s\n", SvPV_nolen(ST(0)));
> }
>
>Would print "Booting package Foo".
>
Indeed.  For some reason I'd never thought of BOOT: as an XSUB.  I don't 
know what I thought it was really; I guess I'd never really thought 
about it much at all.

>But beware inheritance.
>i.e. if someone derives class Baz from Foo 
>and then bootstrap's it you will get Baz not Foo as class name.
>
OK.  My modules are not OO, so that shouldn't be a problem.

>>The Foo.pm file itself called XSLoader::load('Foo', $VERSION) within the 
>>scope of "package Foo;".  Is there any way of "getting back" to that?
>>    
>>
>
>well you could eval_pv("caller(3)") or some such but this is getting 
>very involved.  Doing equivalent oc caller() in XS code is of course 
>possible but very messy.
>
That also works (using caller(2), in fact), but it's not nice since it's 
not clear that "2" will always be the right number: changes to the 
innards of DynaLoader could mess up the counting.  This works too, but 
still isn't fool-proof and is already looking horrible:

warn("Booting package %s\n", SvPV_nolen(eval_pv("my $i = 0; my $package 
= ''; do { $package = caller($i++) } until $package !~ 
/main|DynaLoader/; $package", 0)));

>>The BOOT: section is destined for a .xs file to be INCLUDE'd by the .xs 
>>files in each of two sub-directories:
>>
>>Common.xs
>>Foo/Foo.xs // INCLUDE's ../Common.xs
>>Bar/Bar.xs // INCLUDE's ../Common.xs
>>    
>>
>
>  
>
>>I wanted it to automatically "know" what package it is in 
>>    
>>
>
>IT ISN'T "IN" A PACKAGE - it is only called from a (chain of) package(s).
>
>  
>
>>since I can't 
>>hard-code the package name into it 
>>    
>>
>
>
>If you explained why it needs to know and _exactly_ what it needs to 
>know I may be able to help.
>
<BAIT>It needs to know what package it is in.</BAIT> ;-)

OK, OK, I've got it now.  It's not in a package.

I was going to have it set the name of a debug variable which a (shared) 
IsDebug() function would use:

// Shared C code
static char debug_var[64];
static bool IsDebug(pTHX) {
    return SvTRUE(get_sv(debug_var, FALSE));
}

// Shared XS code
BOOT:
{
    strcpy(debug_var, SvPV_nolen(ST(0)));
    strcat(debug_var, "::Debug");
}

so then XS code in Foo.xs and Bar.xs can each just say "if 
(IsDebug(aTHX)) { ... }" without needing to tell IsDebug() which package 
to lookup the $Debug variable in.

It's not going to work, though, because it is possible (although 
unlikely in this case) that a single program might use both modules, so 
they'll be fighting over debug_var.

I might as well just have separate IsDebug() functions in each .xs file, 
I suppose.

>>(other than putting separate copies 
>>of it into each sub-directory's .xs file).
>>    
>>
>
>Is that so bad?
>
It was laziness backfiring.  "Why have two IsDebug() functions which are 
nearly identical," I thought to myself.

>After all you are (probably) going to have to have a Foo.pm 
>to call XSLoader('Foo')
>
It calls XSLoader::load(__PACKAGE__) actually, but yes, I still have 
that in two places.

>Have you considered writing 
>
>Foo.xs.PL 
>
>which generates Foo.xs ?
>  
>
I hadn't.  That's an idea, but I'm really wondering whether it's worth 
it now...

- Steve



------------------------------------------------
Radan Computational Ltd.

The information contained in this message and any files transmitted with it are 
confidential and intended for the addressee(s) only.  If you have received this 
message in error or there are any problems, please notify the sender immediately.  The 
unauthorized use, disclosure, copying or alteration of this message is strictly 
forbidden.  Note that any views or opinions presented in this email are solely those 
of the author and do not necessarily represent those of Radan Computational Ltd.  The 
recipient(s) of this message should check it and any attached files for viruses: Radan 
Computational will accept no liability for any damage caused by any virus transmitted 
by this email.

Reply via email to