bmdhacks has asked for the wisdom of the Perl Monks concerning the following question:

I've got a perlxs module that maps a pointer to a C struct to a perl object. Here's the typemap:
TYPEMAP cstruct * T_OBJECT
My question is, in my new() method, I would like to return undef on failure. What is the correct method for doing this? Does something like this work:
cstruct * new( field ) int field; CODE: if( something_wrong() ) { /*** is this correct below??? ***/ RETVAL = (cstruct *)&PL_sv__undef; } OUTPUT: RETVAL
Is the cast above the correct way? Or should I have my constructor return an SV* and then coerce my pointer into an IV? Thanks for the help.

Replies are listed 'Best First'.
(tye)Re: perlxs new() returning undef
by tye (Sage) on Mar 14, 2001 at 01:09 UTC

    First, I find no T_OBJECT in my typemap file. Perhaps you meant T_PTROBJ?

    If so, then no, RETVAL= PL_sv__undef isn't the thing to do. When in doubt, use the source! From typemap:

    INPUT T_PTROBJ if (sv_derived_from($arg, \"${ntype}\")) { IV tmp = SvIV((SV*)SvRV($arg)); $var = INT2PTR($type,tmp); } else croak(\"$var is not of type ${ntype}\") OUTPUT T_PTROBJ sv_setref_pv($arg, \"${ntype}\", (void*)$var);
    so your code ends up doing: sv_setref_pv(ST(0),"cstruct",(void*)&PL_sv__undef); so you'd get a new object that is a blessed reference to undef (well, unless that attempt fails, which it probably does).

    You have a couple of ways you can go. You could extend the typemap to handle a failure case:

    OUTPUT OUTPUT T_PTROBJ if( NULL != $var ) sv_setref_pv($arg, \"${ntype}\", (void*)$var); else sv_setsv( $arg, &PL_sv__undef );

    Or something close to that.

    Update: The "other ways" I decided not to describe since they seemed inferior after I saw how easy that was.

            - tye (but my friends call me "Tye")