SBM MODSCRIPT, PART 14 - Checking the Type of a Variable

When interacting with a variable, it is sometimes useful to know what type it has been initialized as. This can be especially useful when working with the results of a from_json() call, where the scripting engine has parsed a blob of JSON and then you need to figure out how to interact with it. The following utility function can be invoked on any var.

  • type_name() -> string: returns a string value denoting the underlying type of the variable, such as "Vector", "Map", "int", "Variant", etc.
  • is_var_undef() -> bool: returns true if the variable has not yet been assigned a type (uninitialized).
  • is_var_null() -> bool: returns true if the variable was initialized by a null, which occurs when from_json() encounters a null.

Example:

def processJSONObj( r ) {
  if ( r.is_var_null() ) {
    Ext.WriteStream( "null\n" );
    continue;
  }
  switch ( r.type_name() ) {
    case( "Vector" ) {
      Ext.WriteStream( "[ " );
      for ( v : r ) {
        processJSONObj( v );
      }
      Ext.WriteStream( " ]\n" );
      break;
    }
    case( "Map" ) {
      Ext.WriteStream( "{ " );
      for ( prop : r ) {
        Ext.WriteStream( prop.first + ": " );
        processJSONObj( prop.second );
      }
      Ext.WriteStream( " }\n" );
      break;
    }
    case( "String" ) {
      Ext.WriteStream( "\"" + r + "\"\n" );
      break;
    }
    default {
      Ext.WriteStream( r + "\n" );
      break;
    }
  }
}

var result = "{
    \"array\": [1,2,3,\"textData\",{ \"a\": 1, \"b\": 2 }],
    \"intData\": 5,
    \"doubleData\": 4.5,
    \"stringData\": \"Welcome to ModScript\"
}".from_json();

processJSONObj( result );

 

SBM ModScript - Table of Contents

SBM ModScript, Part 13 - Base64Encode
SBM MODSCRIPT, PART 15 - Singletons

Comments 4

 
Paul Thompson on Friday, 21 December 2018 17:20

Don:
It seems that "type_name()", "is_var_undef()" and "is_var_null()" can be called as utility functions (what I consider "utility functions" anyway ;)
) or used as methods. I.e. both of the following work:


var x = type_name(r) ;
var y = r.type_name() ;



Don: It seems that "type_name()", "is_var_undef()" and "is_var_null()" can be called as utility functions (what I consider "utility functions" anyway ;) ) or used as methods. I.e. both of the following work: [quote] var x = type_name(r) ; var y = r.type_name() ; [/quote]
Don Inghram on Friday, 21 December 2018 17:26

Paul, those particular functions are part of the engine and interact with the "var" wrapper rather than the object that the var is holding. Yes, you can invoke it as type_name(r) or r.type_name().

Paul, those particular functions are part of the engine and interact with the "var" wrapper rather than the object that the var is holding. Yes, you can invoke it as type_name(r) or r.type_name().
Paul Thompson on Monday, 14 January 2019 00:17

I created a ModScript function that returns the chai type name and, for Variants, the VBScript variable type number and typename and the AppScript subtype name.


/*

Return a string describing what type of thing the param is.
For a native chai type, the format of the returned string is:
chai:
If the native chai type is a "Variant", the format of the returned string is:
chai:Variant / VBScript VarType: () [/ Object[ Is Nothing]] /
Where
is value returned by the VarType function
is the VBScript type name associated with
If the variable is a VBScript "Object" type, then "Object" appears.
If the variable is a VBScript "Object" that is set to the system value "Nothing" then " Is Nothing" appears
is the value returned by "TypeName" function. If the variable
is an AppScript type like "AppRecordList", "VarRecord", "Field", etc, that will show up here.

Examples:
global DESCR_FLD_DBNAME = string( "DESCRIPTION" ); // DESCR_FLD_DBNAME is a chai:string
global TS_SYSFLD_DESC = int( 5 ); // TS_SYSFLD_DESC is a chai:int

var vfl_CurrentItem = Shell.Item().Fields(); // vfl_CurrentItem is a chai:VarFieldList

var fld_DescrFld = vfl_CurrentItem.FindField(DESCR_FLD_DBNAME); // fld_DescrFld is a chai:Field

var fld_DescrFld = Variant();
fld_DescrFld = vfl_CurrentItem.FindField(DESCR_FLD_DBNAME); // fld_DescrFld is a chai:Variant / VBScript VarType:9 (Automation object) / Object / Field

var b_upd = fld_DescrFld.AppendJournalText("Test") // chai:bool=True

*/


def VarInfo( r ) {
// If the param is undefined don't do anything else with it.
if ( r.is_var_undef() ) {
return "chai:UNDEFINED";
// If the param is defined by NULL, also don't do anything with it.
} else if ( r.is_var_null() ) {
return "chai:NULL";
} else {
var str ;
str = "chai:" &&& r.type_name() ;

// If the Chai type is ModScript "Variant" type, i.e. a VBScript type object, then use the VBScript functions to get more info.
if (r.type_name() == "Variant") {
// Append the VBScript variable type number and it's related text.
str = str &&& " / VBScript VarType:" &&& VarType(r) &&& " (" ;
switch (VarType(r)){
case(vbEmpty) { str = str &&& "Empty"; break;}
case(vbNull) { str = str &&& "Null"; break;}
case(vbInteger) { str = str &&& "Integer"; break;}
case(vbLong) { str = str &&& "Long integer"; break;}
case(vbSingle) { str = str &&& "Single"; break;}
case(vbDouble) { str = str &&& "Double"; break;}
case(vbCurrency) { str = str &&& "Currency"; break;}
case(vbDate) { str = str &&& "Date"; break;}
case(vbString) { str = str &&& "String"; break;}
case(vbObject) { str = str &&& "Automation object"; break;}
case(vbError) { str = str &&& "Error"; break;}
case(vbBoolean) { str = str &&& "Boolean"; break;}
case(vbVariant) { str = str &&& "Variant()"; break;}
case(vbDataObject) { str = str &&& "Data-access object"; break;}
case(vbByte) { str = str &&& "Byte"; break;}
case(vbArray) { str = str &&& "Array"; break;}
default { str = str &&& "-unknown VB type-" ; break ; }
}
str = str &&& ")" ;
if (IsObject(r)) {
str = str &&& " / Object" ;
if (r is Nothing) { str = str &&& " Is Nothing" ; }
}
// Append the AppScript subtype name using the VBScript function.
str = str &&& " / " &&& TypeName(r) ;

}
return str;
}
}

I created a ModScript function that returns the chai type name and, for Variants, the VBScript variable type number and typename and the AppScript subtype name. [quote]/* Return a string describing what type of thing the param is. For a native chai type, the format of the returned string is: chai: If the native chai type is a "Variant", the format of the returned string is: chai:Variant / VBScript VarType: () [/ Object[ Is Nothing]] / Where is value returned by the VarType function is the VBScript type name associated with If the variable is a VBScript "Object" type, then "Object" appears. If the variable is a VBScript "Object" that is set to the system value "Nothing" then " Is Nothing" appears is the value returned by "TypeName" function. If the variable is an AppScript type like "AppRecordList", "VarRecord", "Field", etc, that will show up here. Examples: global DESCR_FLD_DBNAME = string( "DESCRIPTION" ); // DESCR_FLD_DBNAME is a chai:string global TS_SYSFLD_DESC = int( 5 ); // TS_SYSFLD_DESC is a chai:int var vfl_CurrentItem = Shell.Item().Fields(); // vfl_CurrentItem is a chai:VarFieldList var fld_DescrFld = vfl_CurrentItem.FindField(DESCR_FLD_DBNAME); // fld_DescrFld is a chai:Field var fld_DescrFld = Variant(); fld_DescrFld = vfl_CurrentItem.FindField(DESCR_FLD_DBNAME); // fld_DescrFld is a chai:Variant / VBScript VarType:9 (Automation object) / Object / Field var b_upd = fld_DescrFld.AppendJournalText("Test") // chai:bool=True */ def VarInfo( r ) { // If the param is undefined don't do anything else with it. if ( r.is_var_undef() ) { return "chai:UNDEFINED"; // If the param is defined by NULL, also don't do anything with it. } else if ( r.is_var_null() ) { return "chai:NULL"; } else { var str ; str = "chai:" &&& r.type_name() ; // If the Chai type is ModScript "Variant" type, i.e. a VBScript type object, then use the VBScript functions to get more info. if (r.type_name() == "Variant") { // Append the VBScript variable type number and it's related text. str = str &&& " / VBScript VarType:" &&& VarType(r) &&& " (" ; switch (VarType(r)){ case(vbEmpty) { str = str &&& "Empty"; break;} case(vbNull) { str = str &&& "Null"; break;} case(vbInteger) { str = str &&& "Integer"; break;} case(vbLong) { str = str &&& "Long integer"; break;} case(vbSingle) { str = str &&& "Single"; break;} case(vbDouble) { str = str &&& "Double"; break;} case(vbCurrency) { str = str &&& "Currency"; break;} case(vbDate) { str = str &&& "Date"; break;} case(vbString) { str = str &&& "String"; break;} case(vbObject) { str = str &&& "Automation object"; break;} case(vbError) { str = str &&& "Error"; break;} case(vbBoolean) { str = str &&& "Boolean"; break;} case(vbVariant) { str = str &&& "Variant()"; break;} case(vbDataObject) { str = str &&& "Data-access object"; break;} case(vbByte) { str = str &&& "Byte"; break;} case(vbArray) { str = str &&& "Array"; break;} default { str = str &&& "-unknown VB type-" ; break ; } } str = str &&& ")" ; if (IsObject(r)) { str = str &&& " / Object" ; if (r is Nothing) { str = str &&& " Is Nothing" ; } } // Append the AppScript subtype name using the VBScript function. str = str &&& " / " &&& TypeName(r) ; } return str; } } [/quote]
Don Inghram on Monday, 14 January 2019 11:20

Nice job, Paul.

Nice job, Paul.

Recent Tweets