Website hosting service by Active-Venture.com
  

 Back to Index

Returning Undef And Empty Lists

Occasionally the programmer will want to return simply undef or an empty list if a function fails rather than a separate status value. The rpcb_gettime() function offers just this situation. If the function succeeds we would like to have it return the time and if it fails we would like to have undef returned. In the following Perl code the value of $timep will either be undef or it will be a valid time.

 
     $timep = rpcb_gettime( "localhost" );  

The following XSUB uses the SV * return type as a mnemonic only, and uses a CODE: block to indicate to the compiler that the programmer has supplied all the necessary code. The sv_newmortal() call will initialize the return value to undef, making that the default return value.

 
     SV *
     rpcb_gettime(host)
          char *  host
	PREINIT:
          time_t  timep;
          bool_t x;
        CODE:
          ST(0) = sv_newmortal();
          if( rpcb_gettime( host, &timep ) )
               sv_setnv( ST(0), (double)timep);  

The next example demonstrates how one would place an explicit undef in the return value, should the need arise.

 
     SV *
     rpcb_gettime(host)
          char *  host
	PREINIT:
          time_t  timep;
          bool_t x;
        CODE:
          ST(0) = sv_newmortal();
          if( rpcb_gettime( host, &timep ) ){
               sv_setnv( ST(0), (double)timep);
          }
          else{
               ST(0) = &PL_sv_undef;
          }  

To return an empty list one must use a PPCODE: block and then not push return values on the stack.

 
     void
     rpcb_gettime(host)
          char *host
	PREINIT:
          time_t  timep;
        PPCODE:
          if( rpcb_gettime( host, &timep ) )
               PUSHs(sv_2mortal(newSViv(timep)));
          else{
	      /* Nothing pushed on stack, so an empty
	       * list is implicitly returned. */
          }  

Some people may be inclined to include an explicit return in the above XSUB, rather than letting control fall through to the end. In those situations XSRETURN_EMPTY should be used, instead. This will ensure that the XSUB stack is properly adjusted. Consult perlguts/"API LISTING" for other XSRETURN macros.

Since XSRETURN_* macros can be used with CODE blocks as well, one can rewrite this example as:

 
     int
     rpcb_gettime(host)
          char *host
	PREINIT:
          time_t  timep;
        CODE:
          RETVAL = rpcb_gettime( host, &timep );
	  if (RETVAL == 0)
		XSRETURN_UNDEF;
	OUTPUT:
	  RETVAL  

In fact, one can put this check into a POSTCALL: section as well. Together with PREINIT: simplifications, this leads to:

 
     int
     rpcb_gettime(host)
          char *host
          time_t  timep;
	POSTCALL:
	  if (RETVAL == 0)
		XSRETURN_UNDEF; 

 

  

 

Domain name registration - 
Register cheap domain name from $7.95 and enjoy free domain services 
 

Cheap domain name search service -
Domain name services at just
$8.95/year only
 

Register domain name -
Buy domain name registration and cheap domain transfer at low, affordable price.

© 2002-2004 Active-Venture.com Web Site Hosting Service

 

[ The most horrifying thing about Unix is that, no matter how many times you hit yourself over the head with it, you never quite manage to lose consciousness. It just goes on and on.   ]

 

 
 
 

Disclaimer: This documentation is provided only for the benefits of our web hosting customers.
For authoritative source of the documentation, please refer to http://www.perldoc.com