This might be a useful description for extension writers, how to deal
with mortalness of variables...

If an object has to hold a lot of instance variables, it is the  
natural choice to make it a hash reference. The key/value pairs of  
the referenced hash table are the attribute names with their  
associated values. The following example of a ``Query'' method will  
create a hash table that contains some information about a table. The  
keys NUMROWS and NUMFIELDS hold information about the table and the  
key RESULT contains a pointer to a C-struct which allows direct  
access to individual rows of the table. It is assumed, that the  
C-function imposes the need to free the data associated with the  
struct.

The hash has to be created as a mortal variable in the constructor  
method, so that perl will call a destructor method when the object is  
no longer used. You can do so with the statement

     hv = (HV*)sv_2mortal((SV*)newHV());

in your XS code. After that you can fill the hash with data you get  
from your C-function(s).

hv_store(hv,"NUMROWS",7,(SV*)newSViv((IV)msqlNumRows(result)),0);
hv_store(hv,"NUMFIELDS",9,(SV*)newSViv((IV)msqlNumFields(result)),0);
hv_store(hv,"RESULT",6,(SV*)newSViv((IV)result),0);

Note, that these newly created scalar values don't need to be mortal,  
as they will vanish, as soon as the hashtable is undef'd by the  
destructor. You finish the XS CODE: section by blessing a reference  
to the newly created hash table.

    rv = newRV((SV*)hv);
    stash = gv_stashpv(package, TRUE);
    ST(0) = sv_2mortal(sv_bless(rv, stash));

stash is short for symbol table hash, package has been declared by  
yourself, and is a char* specifying into which package you are  
blessing (which can be a different one from the PACKAGE where you are  
coding the Query method).

>From the perl side the ``Query'' method is accessed with

    $sth = $dbh->Query("select * from FOO");

$dbh is already an object in the package we have coded the Query  
method in. $sth is then an object with its own methods and with an  
own destructor. $sth->{NUMROWS} will return the number of rows of the  
table and some other methods will be able to access the individual  
rows of the table. The class which is associated with $sth has a  
destructor that tries to find the value of $sth->{RESULT}, because  
it's duty is to actually free the result in memory:

  if (svp = hv_fetch(handle,"RESULT",6,FALSE)){
    sv = *svp;
    result = (Mysql__Result)SvIV(sv);
  }
  if (result){
    mysql_FreeResult(result);

As soon as somebody uses $sth for something else or undef's it, this  
destructor comes into play, gets the `result' pointer out of the hash  
table and frees the struct it is pointing to.


--andreas





