Using Tie in XSUBs

Using Tie in XSUBs

am 11.06.2005 00:47:31 von Robert Jordan

Hi!

I wrote a tied array implementation as an XSUB. The XSUB module
contains other packages as well. From a method of a package
I want to return a tied arrayref of my own tied array class,
something like that (expressed in Perl code):

package Foo;
sub get_list {
my $self = shift;
my @a;
tie @a, 'Foo::Array', @_; # how do I implement that in C??
return \@a;
}

package Foo::Array;
sub TIEARRAY { ... }
sub FETCH { ... }
....

I read the section "Understanding the Magic of Tied Hashes and
Arrays" of perlguts, but, despite its name, it covers only hashes.
Not that I unterstood it either ;-)

Thanks!
Rob

Re: Using Tie in XSUBs

am 11.06.2005 09:14:50 von tassilo.von.parseval

Also sprach Robert Jordan:

> I wrote a tied array implementation as an XSUB. The XSUB module
> contains other packages as well. From a method of a package
> I want to return a tied arrayref of my own tied array class,
> something like that (expressed in Perl code):
>
> package Foo;
> sub get_list {
> my $self = shift;
> my @a;
> tie @a, 'Foo::Array', @_; # how do I implement that in C??
> return \@a;
> }
>
> package Foo::Array;
> sub TIEARRAY { ... }
> sub FETCH { ... }
> ...
>
> I read the section "Understanding the Magic of Tied Hashes and
> Arrays" of perlguts, but, despite its name, it covers only hashes.
> Not that I unterstood it either ;-)

For some things in XS it is best to consult the perl source for
reference, in this case pp_tie().

I think for a tied array you have to do this [untested]:

void
tie_this (av)
SV *av;
PROTOTYPE: \@
CODE:
{
/* create blessed array-reference */
HV *stash = gv_stashpv("Foo::Array", TRUE);
SV *sv = newRV_noinc((SV*)newAV());
sv_bless(sv, stash);

/* make av a blessed array associated with
* sv as its internal object */
sv_magic(SvRV(av), sv, PERL_MAGIC_tied, Nullch, 0);
XSRETURN_EMPTY;
}

'sv' in the above might need to be mortalized, not sure right now.

The above gets away without any TIEARRAY method. All the other methods
(FETCH, etc.) you can define as ordinary XSUBs which will receive 'sv'
as their first argument.

Usage is simple:

tie_this(my @array);
# @array should now be tied

Tassilo
--
use bigint;
$n=714233503437702801613970263303373711390544118542200534375 65440;
$m=-8,;;$_=$n&(0xff)<<$m,,$_>>=$m,,print+chr,,while(($m+=8)<=200);

Re: Using Tie in XSUBs

am 15.06.2005 22:56:10 von Robert Jordan

Tassilo,

>>I read the section "Understanding the Magic of Tied Hashes and
>>Arrays" of perlguts, but, despite its name, it covers only hashes.
>>Not that I unterstood it either ;-)
>
>
> For some things in XS it is best to consult the perl source for
> reference, in this case pp_tie().

Wow, call me an idiot ;-) I didn't realize that AVs are upgraded
with sv_magic() as well. I sorted that out with the help of
the perl sources and of your sample:

/* create AV ref */
AV *ref = newRV_noinc ((SV *) newAV ());

/* tie the AV with the already blessed `obj' */
sv_magic (SvRV (ref), obj, PERL_MAGIC_tied, Nullch, 0);

Thanks!
Rob