/*
 * $Id: objfunc.txt 12560 2009-09-19 14:30:32Z april $
 */

/*
 * The following parts are Copyright of the individual authors.
 * www - http://www.harbour-project.org
 *
 * Copyright 1999-2000 Chen Kedem <niki@actcom.co.il>
 *    Documentation for: __objHasData(), __objHasMethod(), __objGetMsgList(),
 *                       __objGetMethodList(), __objGetValueList(),
 *                       __ObjSetValueList(), __objAddMethod(),
 *                       __objAddInline(), __objAddData(), __objModMethod(),
 *                       __objModInline(), __objDelMethod(), __objDelInline(),
 *                       __objDelData(), __objDerivedFrom()
 *
 * See COPYING for licensing terms.
 *
 */

/*  $DOC$
 *  $TEMPLATE$
 *      Function
 *  $NAME$
 *      __objHasData()
 *  $CATEGORY$
 *      API
 *  $SUBCATEGORY$
 *      Objects
 *  $ONELINER$
 *      Determine whether a symbol exist in object as DATA
 *  $SYNTAX$
 *      __objHasData( <oObject>, <cSymbol> ) --> lExist
 *  $ARGUMENTS$
 *      <oObject> is an object to scan.
 *
 *      <cSymbol> is the name of the symbol to look for.
 *  $RETURNS$
 *      __objHasData() return .T. if the given <cSymbol> exist as DATA
 *      (instance variable) in object <oObject), .F. if it does not exist.
 *  $DESCRIPTION$
 *      __objHasData() is a low level class support function that let you
 *      find out if a symbol is an instance variable in a given object.
 *  $EXAMPLES$
 *      oB := TBrowseNew( 0, 0, 24, 79 )
 *      ? __objHasData( oB, "nLeft" )      // this should return .T.
 *      ? __objHasData( oB, "lBugFree" )   // hopefully this should be .F.
 *      ? __objHasData( oB, "Left" )       // .F. since this is a METHOD
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      H
 *  $FILES$
 *      Library is rtl
 *  $SEEALSO$
 *      __ObjGetMethodList(),__objGetMsgList(),__objHasMethod()
 *  $END$
 */

/*  $DOC$
 *  $TEMPLATE$
 *      Function
 *  $NAME$
 *      __objHasMethod()
 *  $CATEGORY$
 *      API
 *  $SUBCATEGORY$
 *      Objects
 *  $ONELINER$
 *      Determine whether a symbol exist in object as METHOD
 *  $SYNTAX$
 *      __objHasMethod( <oObject>, <cSymbol> ) --> lExist
 *  $ARGUMENTS$
 *      <oObject> is an object to scan.
 *
 *      <cSymbol> is the name of the symbol to look for.
 *  $RETURNS$
 *      __objHasMethod() return .T. if the given <cSymbol> exist as METHOD
 *      (class function) in object <oObject), .F. if it does not exist.
 *  $DESCRIPTION$
 *      __objHasMethod() is a low level class support function that let you
 *      find out if a symbol is a class function in a given object.
 *  $EXAMPLES$
 *      oB := TBrowseNew( 0, 0, 24, 79 )
 *      ? __objHasMethod( oB, "nLeft" )      // .F. since this is a DATA
 *      ? __objHasMethod( oB, "FixBugs" )    // hopefully this should be .F.
 *      ? __objHasMethod( oB, "Left" )       // this should return .T.
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      H
 *  $FILES$
 *      Library is rtl
 *  $SEEALSO$
 *      __ObjGetMethodList(),__objGetMsgList(),__objHasData()
 *  $END$
 */

/*  $DOC$
 *  $TEMPLATE$
 *      Function
 *  $NAME$
 *      __objGetMsgList()
 *  $CATEGORY$
 *      API
 *  $SUBCATEGORY$
 *      Objects
 *  $ONELINER$
 *      Return names of all DATA or METHOD for a given object
 *  $SYNTAX$
 *      __objGetMsgList( <oObject>, [<lData>], [nClassType] ) --> aNames
 *  $ARGUMENTS$
 *      <oObject> is an object to scan.
 *
 *      <lData> is an optional logical value that specifies the information
 *      to return. A value of .T. instruct the function to return list of
 *      all DATA names, .F. return list of all METHOD names. Default value
 *      is .T.
 *
 *      <nClassType> is on optional numeric code for selecting which class
 *      type to return. Default value is HB_MSGLISTALL, returning the whole
 *      list.
 *  $RETURNS$
 *      __objGetMsgList() return an array of character stings with all DATA
 *      names or all METHOD names for a given object. __objGetMsgList()
 *      would return an empty array {} if the given object does not contain
 *      the requested information.
 *  $DESCRIPTION$
 *      __objGetMsgList() is a low level class support function that let you
 *      find all instance variable or method names for a given object.
 *
 *      If specified, the following table shows the values for <nClassType>
 *      that allow you to distinguish between DATA and CLASSDATA:
 *
 *     <table>
 *      hboo.ch           Value   Meaning
 *
 *      HB_MSGLISTALL     0       All types
 *      HB_MSGLISTCLASS   1       CLASSDATA only
 *      HB_MSGLISTPURE    2       DATA only
 *     </table>
 *
 *      DATA are instance variable usable within each object from a class,
 *      where each object has its own DATAs.
 *
 *      CLASSDATA are shared by all objects from a Class, so the changed
 *      value within Object1 will be reflected when accessing the CLASSDATA
 *      from Object2.
 *  $EXAMPLES$
 *      // show information about TBrowse class
 *      oB := TBrowseNew( 0, 0, 24, 79 )
 *      aData      := __objGetMsgList( oB, .T. )
 *      aClassData := __objGetMsgList( oB, .T., HB_MSGLISTCLASS )
 *      aMethod    := __objGetMsgList( oB, .F. )
 *      FOR i = 1 to len ( aData )
 *          ? "DATA name:", aData[ i ]
 *      NEXT
 *      FOR i = 1 to len ( aClassData )
 *          ? "CLASSDATA name:", aClassData[ i ]
 *      NEXT
 *      FOR i = 1 to len ( aMethod )
 *          ? "METHOD name:", aMethod[ i ]
 *      NEXT
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      H
 *  $FILES$
 *      Header file is hboo.ch
 *      Library is rtl
 *  $SEEALSO$
 *      __ObjGetMethodList(),__ObjGetValueList(),__objHasData(),__objHasMethod()
 *  $END$
 */

/*  $DOC$
 *  $TEMPLATE$
 *      Function
 *  $NAME$
 *      __objGetMethodList()
 *  $CATEGORY$
 *      API
 *  $SUBCATEGORY$
 *      Objects
 *  $ONELINER$
 *      Return names of all METHOD for a given object
 *  $SYNTAX$
 *      __objGetMethodList( <oObject> ) --> aMethodNames
 *  $ARGUMENTS$
 *      <oObject> is an object to scan.
 *  $RETURNS$
 *      __objGetMethodList() return an array of character stings with all
 *      METHOD names for a given object. __objGetMethodList() would return
 *      an empty array {} if the given object does not contain any METHOD.
 *  $DESCRIPTION$
 *      __objGetMethodList() is a low level class support function that let
 *      you find all class functions names for a given object.
 *      It is equivalent to __objGetMsgList( oObject, .F. ).
 *  $EXAMPLES$
 *      // show information about TBrowse class
 *      oB := TBrowseNew( 0, 0, 24, 79 )
 *      aMethod := __objGetMethodList( oB )
 *      FOR i = 1 to len ( aMethod )
 *          ? "METHOD name:", aMethod[ i ]
 *      NEXT
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      H
 *  $FILES$
 *      Library is rtl
 *  $SEEALSO$
 *      __objGetMsgList(),__ObjGetValueList(),__objHasData(),__objHasMethod()
 *  $END$
 */

/*  $DOC$
 *  $TEMPLATE$
 *      Function
 *  $NAME$
 *      __objGetValueList()
 *  $CATEGORY$
 *      API
 *  $SUBCATEGORY$
 *      Objects
 *  $ONELINER$
 *      Return an array of DATA names and values for a given object
 *  $SYNTAX$
 *      __objGetValueList( <oObject>, [<aExcept>] ) --> aData
 *  $ARGUMENTS$
 *      <oObject> is an object to scan.
 *
 *      <aExcept> is an optional array with DATA names you want to exclude
 *      from the scan.
 *  $RETURNS$
 *      __objGetValueList() return a 2D array that contain pairs of a DATA
 *      symbol name and the value of DATA. __objGetValueList() would return
 *      an empty array {} if the given object does not contain the requested
 *      information.
 *  $DESCRIPTION$
 *      __objGetValueList() is a low level class support function that
 *      return an array with DATA names and value, each array element is a
 *      pair of: aData[ i, HB_OO_DATA_SYMBOL ] contain the symbol name
 *               aData[ i, HB_OO_DATA_VALUE  ] contain the value of DATA
 *  $EXAMPLES$
 *      // show information about TBrowse class
 *      oB := TBrowseNew( 0, 0, 24, 79 )
 *      aData := __objGetValueList( oB )
 *      FOR i = 1 to len ( aData )
 *          ? "DATA name:", aData[ i, HB_OO_DATA_SYMBOL ], ;
 *            "    value=", aData[ i, HB_OO_DATA_VALUE  ]
 *      NEXT
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      H
 *  $FILES$
 *      Header file is hboo.ch
 *      Library is rtl
 *  $SEEALSO$
 *      __objGetMethodList(),__objGetMsgList(),__objHasData(),__objHasMethod(),__ObjSetValueList()
 *  $END$
 */

/*  $DOC$
 *  $TEMPLATE$
 *      Function
 *  $NAME$
 *      __ObjSetValueList()
 *  $CATEGORY$
 *      API
 *  $SUBCATEGORY$
 *      Objects
 *  $ONELINER$
 *      Set object with an array of DATA names and values
 *  $SYNTAX$
 *      __ObjSetValueList( <oObject>, <aData> ) --> oObject
 *  $ARGUMENTS$
 *      <oObject> is an object to set.
 *
 *      <aData> is a 2D array with a pair of instance variables and values
 *      for setting those variable.
 *  $RETURNS$
 *      __ObjSetValueList() return a reference to <oObject>.
 *  $DESCRIPTION$
 *      __ObjSetValueList() is a low level class support function that let
 *      you set a group of instance variables with values. each array
 *      element in <aData> is a pair of:
 *      aData[ i, HB_OO_DATA_SYMBOL ] which contain the variable name to set
 *      aData[ i, HB_OO_DATA_VALUE  ] contain the new variable value.
 *  $EXAMPLES$
 *      // set some TBrowse instance variable
 *      oB := TBrowse():New()
 *      aData := array( 4, 2 )
 *      aData[ 1, HB_OO_DATA_SYMBOL ] = "nTop"
 *      aData[ 1, HB_OO_DATA_VALUE  ] = 1
 *      aData[ 2, HB_OO_DATA_SYMBOL ] = "nLeft"
 *      aData[ 2, HB_OO_DATA_VALUE  ] = 10
 *      aData[ 3, HB_OO_DATA_SYMBOL ] = "nBottom"
 *      aData[ 3, HB_OO_DATA_VALUE  ] = 20
 *      aData[ 4, HB_OO_DATA_SYMBOL ] = "nRight"
 *      aData[ 4, HB_OO_DATA_VALUE  ] = 70
 *      __ObjSetValueList( oB, aData )
 *      ? oB:nTop      // 1
 *      ? oB:nLeft     // 10
 *      ? oB:nBottom   // 20
 *      ? oB:nRight    // 70
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      H
 *  $FILES$
 *      Header file is hboo.ch
 *      Library is rtl
 *  $SEEALSO$
 *      __ObjGetValueList()
 *  $END$
 */

/*  $DOC$
 *  $TEMPLATE$
 *      Function
 *  $NAME$
 *      __objAddMethod()
 *  $CATEGORY$
 *      API
 *  $SUBCATEGORY$
 *      Objects
 *  $ONELINER$
 *      Add a METHOD to an already existing class
 *  $SYNTAX$
 *      __objAddMethod( <oObject>, <cMethodName>, <nFuncPtr> ) --> oObject
 *  $ARGUMENTS$
 *      <oObject> is the object to work on.
 *
 *      <cMethodName> is the symbol name of the new METHOD to add.
 *
 *      <nFuncPtr> is a pointer to a function to associate with the method.
 *  $RETURNS$
 *      __objAddMethod() return a reference to <oObject>.
 *  $DESCRIPTION$
 *      __objAddMethod() is a low level class support function that add a
 *      new METHOD to an object. <oObject> is unchanged if a symbol with the
 *      name <cMethodName> already exist in <oObject>.
 *
 *      Note that <nFuncPtr> is a special pointer to a function that was
 *      created using the @ operator, see example below.
 *  $EXAMPLES$
 *      // create a new THappy class and add a Smile method
 *      oHappy := HBClass():New( "THappy" )
 *      __objAddMethod( oHappy, "Smile", @MySmile() )
 *      ? oHappy:Smile( 1 )       // :)
 *      ? oHappy:Smile( 2 )       // ;)
 *      ? oHappy:Smile( 3 )       // *SMILE*
 *
 *      STATIC FUNCTION MySmile( nType )
 *      LOCAL cSmile
 *      DO CASE
 *         CASE nType == 1
 *              cSmile := ":)"
 *         CASE nType == 2
 *              cSmile := ";)"
 *         CASE nType == 3
 *              cSmile := "*SMILE*"
 *      ENDCASE
 *      RETURN cSmile
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      H
 *  $FILES$
 *      Library is rtl
 *  $SEEALSO$
 *      __objAddInline(),__objAddData(),__objDelMethod(),__ObjGetMethodList(),__objGetMsgList(),__objHasMethod(),__objModMethod()
 *  $END$
 */

/*  $DOC$
 *  $TEMPLATE$
 *      Function
 *  $NAME$
 *      __objAddInline()
 *  $CATEGORY$
 *      API
 *  $SUBCATEGORY$
 *      Objects
 *  $ONELINER$
 *      Add an INLINE to an already existing class
 *  $SYNTAX$
 *      __objAddInline( <oObject>, <cInlineName>, <bInline> ) --> oObject
 *  $ARGUMENTS$
 *      <oObject> is the object to work on.
 *
 *      <cInlineName> is the symbol name of the new INLINE to add.
 *
 *      <bInline> is a code block to associate with the INLINE method.
 *  $RETURNS$
 *      __objAddInline() return a reference to <oObject>.
 *  $DESCRIPTION$
 *      __objAddInline() is a low level class support function that add a
 *      new INLINE method to an object. <oObject> is unchanged if a symbol
 *      with the name <cInlineName> already exist in <oObject>.
 *  $EXAMPLES$
 *      // create a new THappy class and add a Smile INLINE method
 *      oHappy  := HBClass():New( "THappy" )
 *      bInline := { | nType | { ":)", ";)", "*SMILE*" }[ nType ] }
 *      __objAddInline( oHappy, "Smile", bInline )
 *      ? oHappy:Smile( 1 )       // :)
 *      ? oHappy:Smile( 2 )       // ;)
 *      ? oHappy:Smile( 3 )       // *SMILE*
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      H
 *  $FILES$
 *      Library is rtl
 *  $SEEALSO$
 *      __objAddData(),__objAddMethod(),__objDelInline(),__ObjGetMethodList(),__objGetMsgList(),__objHasMethod() ,__objModInline()
 *  $END$
 */

/*  $DOC$
 *  $TEMPLATE$
 *      Function
 *  $NAME$
 *      __objAddData()
 *  $CATEGORY$
 *      API
 *  $SUBCATEGORY$
 *      Objects
 *  $ONELINER$
 *      Add a DATA to an already existing class
 *  $SYNTAX$
 *      __objAddData( <oObject>, <cDataName> ) --> oObject
 *  $ARGUMENTS$
 *      <oObject> is the object to work on.
 *
 *      <cDataName> is the symbol name of the new DATA to add.
 *  $RETURNS$
 *      __objAddData() return a reference to <oObject>.
 *  $DESCRIPTION$
 *      __objAddData() is a low level class support function that add a new
 *      DATA to an object. <oObject> is unchanged if a symbol with the name
 *      <cDataName> already exist in <oObject>.
 *  $EXAMPLES$
 *      // create a new THappy class and add a lHappy DATA
 *      oHappy  := HBClass():New( "THappy" )
 *      __objAddData( oHappy, "lHappy" )
 *      oHappy:lHappy := .T.
 *      IF oHappy:lHappy
 *         ? "Happy, Happy, Joy, Joy !!!"
 *      ELSE
 *         ? ":(..."
 *      ENDIF
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      H
 *  $FILES$
 *      Library is rtl
 *  $SEEALSO$
 *      __objAddInline(),__objAddMethod(),__objDelData(),__objGetMsgList(),__ObjGetValueList(),__objHasData(),__ObjSetValueList()
 *  $END$
 */

/*  $DOC$
 *  $TEMPLATE$
 *      Function
 *  $NAME$
 *      __objModMethod()
 *  $CATEGORY$
 *      API
 *  $SUBCATEGORY$
 *      Objects
 *  $ONELINER$
 *      Modify (replace) a METHOD in an already existing class
 *  $SYNTAX$
 *      __objModMethod( <oObject>, <cMethodName>, <nFuncPtr> ) --> oObject
 *  $ARGUMENTS$
 *      <oObject> is the object to work on.
 *
 *      <cMethodName> is the symbol name of the METHOD to modify.
 *
 *      <nFuncPtr> is a pointer to a new function to associate with the
 *      method.
 *  $RETURNS$
 *      __objModMethod() return a reference to <oObject>.
 *  $DESCRIPTION$
 *      __objModMethod() is a low level class support function that modify
 *      a METHOD in an object and replace it with a new function. <oObject>
 *      is unchanged if a symbol with the name <cMethodName> does not exist
 *      in <oObject>. __objModMethod() is used in inheritance mechanism.
 *
 *      Note that <nFuncPtr> is a special pointer to a function that was
 *      created using the @ operator, see example below.
 *  $EXAMPLES$
 *      // create a new THappy class and add a Smile method
 *      oHappy := HBClass():New( "THappy" )
 *      __objAddMethod( oHappy, "Smile", @MySmile() )
 *      ? oHappy:Smile( 1 )       // :)
 *      ? oHappy:Smile( 2 )       // ;)
 *      // replace Smile method with a new function
 *      __objAddMethod( oHappy, "Smile", @YourSmile() )
 *      ? oHappy:Smile( 1 )       // *SMILE*
 *      ? oHappy:Smile( 2 )       // *WINK*
 *
 *      STATIC FUNCTION MySmile( nType )
 *      LOCAL cSmile
 *      DO CASE
 *         CASE nType == 1
 *              cSmile := ":)"
 *         CASE nType == 2
 *              cSmile := ";)"
 *      ENDCASE
 *      RETURN cSmile
 *
 *      STATIC FUNCTION YourSmile( nType )
 *      LOCAL cSmile
 *      DO CASE
 *         CASE nType == 1
 *              cSmile := "*SMILE*"
 *         CASE nType == 2
 *              cSmile := "*WINK*"
 *      ENDCASE
 *      RETURN cSmile
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      H
 *  $FILES$
 *      Library is rtl
 *  $SEEALSO$
 *      __objAddMethod(),__objDelMethod(),__ObjGetMethodList(),__objGetMsgList(),__objHasMethod()
 *  $END$
 */

/*  $DOC$
 *  $TEMPLATE$
 *      Function
 *  $NAME$
 *      __objModInline()
 *  $CATEGORY$
 *      API
 *  $SUBCATEGORY$
 *      Objects
 *  $ONELINER$
 *      Modify (replace) an INLINE method in an already existing class
 *  $SYNTAX$
 *      __objModInline( <oObject>, <cInlineName>, <bInline> ) --> oObject
 *  $ARGUMENTS$
 *      <oObject> is the object to work on.
 *
 *      <cInlineName> is the symbol name of the INLINE method to modify.
 *
 *      <bInline> is a new code block to associate with the INLINE method.
 *  $RETURNS$
 *      __objModInline() return a reference to <oObject>.
 *  $DESCRIPTION$
 *      __objModInline() is a low level class support function that modify
 *      an INLINE method in an object and replace it with a new code block.
 *      <oObject> is unchanged if a symbol with the name <cInlineName> does
 *      not exist in <oObject>. __objModInline() is used in inheritance
 *      mechanism.
 *  $EXAMPLES$
 *      // create a new THappy class and add a Smile INLINE method
 *      oHappy  := HBClass():New( "THappy" )
 *      bMyInline   := { | nType | { ":)", ";)" }[ nType ] }
 *      bYourInline := { | nType | { "*SMILE*", "*WINK*" }[ nType ] }
 *      __objAddInline( oHappy, "Smile", bMyInline )
 *      ? oHappy:Smile( 1 )       // :)
 *      ? oHappy:Smile( 2 )       // ;)
 *      // replace Smile inline method with a new code block
 *      __objModInline( oHappy, "Smile", bYourInline )
 *      ? oHappy:Smile( 1 )       // *SMILE*
 *      ? oHappy:Smile( 2 )       // *WINK*
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      H
 *  $FILES$
 *      Library is rtl
 *  $SEEALSO$
 *      __objAddInline(),__objDelInline(),__ObjGetMethodList(),__objGetMsgList(),__objHasMethod()
 *  $END$
 */

/*  $DOC$
 *  $TEMPLATE$
 *      Function
 *  $NAME$
 *      __objDelMethod()
 *  $CATEGORY$
 *      API
 *  $SUBCATEGORY$
 *      Objects
 *  $ONELINER$
 *      Delete a METHOD  from class
 *  $SYNTAX$
 *      __objDelMethod( <oObject>, <cSymbol> ) --> oObject
 *  $ARGUMENTS$
 *      <oObject> is the object to work on.
 *
 *      <cSymbol> is the symbol name of METHOD or INLINE method to be
 *      deleted (removed) from the object.
 *  $RETURNS$
 *      __objDelMethod() return a reference to <oObject>.
 *  $DESCRIPTION$
 *      __objDelMethod() is a low level class support function that deletes
 *      (removes) a METHOD or an INLINE method from an object. <oObject> is
 *      unchanged if a symbol with the name <cSymbol> does not exist in
 *      <oObject>.
 *
 *      __objDelInline() is exactly the same as __objDelMethod().
 *  $EXAMPLES$
 *      // create a new THappy class and add a Smile method
 *      oHappy := HBClass():New( "THappy" )
 *      __objAddMethod( oHappy, "Smile", @MySmile() )
 *      ? __objHasMethod( oHappy, "Smile" )    // .T.
 *      // remove Smile method
 *      __objDelMethod( oHappy, "Smile" )
 *      ? __objHasMethod( oHappy, "Smile" )    // .F.
 *
 *      STATIC FUNCTION MySmile( nType )
 *      LOCAL cSmile
 *      DO CASE
 *         CASE nType == 1
 *              cSmile := ":)"
 *         CASE nType == 2
 *              cSmile := ";)"
 *      ENDCASE
 *      RETURN cSmile
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      H
 *  $FILES$
 *      Library is rtl
 *  $SEEALSO$
 *      __objAddInline(),__objAddMethod(),__ObjGetMethodList(),__objGetMsgList(),__objHasMethod(),__objModInline(),__objModMethod()
 *  $END$
 */

/*  $DOC$
 *  $TEMPLATE$
 *      Function
 *  $NAME$
 *      __objDelInline()
 *  $CATEGORY$
 *      API
 *  $SUBCATEGORY$
 *      Objects
 *  $ONELINER$
 *      Delete a METHOD INLINE from class
 *  $SYNTAX$
 *      __objDelInline( <oObject>, <cSymbol> ) --> oObject
 *  $ARGUMENTS$
 *      <oObject> is the object to work on.
 *
 *      <cSymbol> is the symbol name of METHOD or INLINE method to be
 *      deleted (removed) from the object.
 *  $RETURNS$
 *      __objDelInMethod() return a reference to <oObject>.
 *  $DESCRIPTION$
 *      __objDelInMethod() is a low level class support function that delete
 *      (remove) a METHOD or an INLINE method from an object. <oObject> is
 *      unchanged if a symbol with the name <cSymbol> does not exist in
 *      <oObject>.
 *  $EXAMPLES$
 *      // create a new THappy class and add a Smile method
 *      oHappy := HBClass():New( "THappy" )
 *      __objAddMethod( oHappy, "Smile", @MySmile() )
 *      ? __objHasMethod( oHappy, "Smile" )    // .T.
 *      // remove Smile method
 *      __objDelInMethod( oHappy, "Smile" )
 *      ? __objHasMethod( oHappy, "Smile" )    // .F.
 *
 *      STATIC FUNCTION MySmile( nType )
 *      LOCAL cSmile
 *      DO CASE
 *         CASE nType == 1
 *              cSmile := ":)"
 *         CASE nType == 2
 *              cSmile := ";)"
 *      ENDCASE
 *      RETURN cSmile
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      H
 *  $FILES$
 *      Library is rtl
 *  $SEEALSO$
 *      __objAddInline(),__objAddMethod(),__ObjGetMethodList(),__objGetMsgList(),__objHasMethod(),__objModInline(),__objModMethod()
 *  $END$
 */

/*  $DOC$
 *  $TEMPLATE$
 *      Function
 *  $NAME$
 *      __objDelData()
 *  $CATEGORY$
 *      API
 *  $SUBCATEGORY$
 *      Objects
 *  $ONELINER$
 *      Delete a DATA (instance variable) from class
 *  $SYNTAX$
 *      __objDelMethod( <oObject>, <cDataName> ) --> oObject
 *  $ARGUMENTS$
 *      <oObject> is the object to work on.
 *
 *      <cDataName> is the symbol name of DATA to be deleted (removed) from
 *      the object.
 *  $RETURNS$
 *      __objDelData() return a reference to <oObject>.
 *  $DESCRIPTION$
 *      __objDelData() is a low level class support function that delete
 *      (remove) a DATA from an object. <oObject> is unchanged if a symbol
 *      with the name <cDataName> does not exist in <oObject>.
 *  $EXAMPLES$
 *      // create a new THappy class and add a lHappy DATA
 *      oHappy  := HBClass():New( "THappy" )
 *      __objAddData( oHappy, "lHappy" )
 *      ? __objHasData( oHappy, "lHappy" )    // .T.
 *      // remove lHappy DATA
 *      __objDelData( oHappy, "lHappy" )
 *      ? __objHasData( oHappy, "lHappy" )    // .F.
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      H
 *  $FILES$
 *      Library is rtl
 *  $SEEALSO$
 *      __objAddData(),__objGetMsgList(),__ObjGetValueList(),__objHasData(),__ObjSetValueList()
 *  $END$
 */

/*  $DOC$
 *  $TEMPLATE$
 *      Function
 *  $NAME$
 *      __objDerivedFrom()
 *  $CATEGORY$
 *      API
 *  $SUBCATEGORY$
 *      Objects
 *  $ONELINER$
 *      Determine whether a class is derived from another class
 *  $SYNTAX$
 *      __objDerivedFrom( <oObject>, <xSuper> ) --> lIsParent
 *  $ARGUMENTS$
 *      <oObject> is the object to check.
 *
 *      <xSuper> is the object that may be a parent. <xSuper> can be either
 *      an Object or a Character string with the class name.
 *  $RETURNS$
 *      __objDerivedFrom() return a logical TRUE (.T.) if <oObject> is
 *      derived from <xSuper>.
 *  $DESCRIPTION$
 *      __objDerivedFrom() is a low level class support function that check
 *      is one class is a super class of the other, or in other words, does
 *      class <oObject> a child or descendant of <xSuper>.
 *  $EXAMPLES$
 *      // Create three classes and check their relations
 *
 *      #include "hbclass.ch"
 *      FUNCTION main()
 *         local oSuper, oObject, oDress
 *         oSuper  := TMood():New()
 *         oObject := THappy():New()
 *         oDress  := TShirt():New()
 *         ? __objDerivedFrom( oObject, oSuper )    // .T.
 *         ? __objDerivedFrom( oSuper, oObject )    // .F.
 *         ? __objDerivedFrom( oObject, oDress )    // .F.
 *      RETURN NIL
 *
 *      CLASS TMood
 *         METHOD New() INLINE Self
 *      ENDCLASS
 *
 *      CLASS THappy FROM TMood
 *         METHOD Smile() INLINE qout( "*smile*" )
 *      ENDCLASS
 *
 *      CLASS TShirt
 *         DATA Color
 *         DATA Size
 *         METHOD New() INLINE Self
 *      ENDCLASS
 *  $STATUS$
 *      R
 *  $COMPLIANCE$
 *      H
 *  $FILES$
 *      Library is rtl
 *  $SEEALSO$
 *      __objHasData(),__ObjHasMethod()
 *  $END$
 */
