Show/Hide Toolbars


NoteThis command is not available in the Core and Vulcan dialects


Creates variables and arrays visible to all routines in an application.


PUBLIC <memVarList>
PUBLIC <idVar> [:= <uValue>] | <ArraySpec> [, ...]
PUBLIC <idVar> [:= <uValue>] [AS <Type> [OF <ClassLibrary>] ]                                                 // FoxPro dialect only
PUBLIC ARRAY <arrayName> ( <nRows> [, <nColumns>] ) [, <arrayName> ( <nRows> [, <nColumns>] ) ]     // FoxPro dialect only
PUBLIC ARRAY <arrayName> [ <nRows> [, <nColumns>] ] [, <arrayName> [ <nRows> [, <nColumns>] ] ]     // FoxPro dialect only


<memVarList>One or more variable names separated by commas.
<idVar>A valid identifier name for the public variable to create.
The idVar may be prefixed with an ampersand (such as PUBLIC &name). In that case the compiler the idVar should contain a string with the name of the variable that is declared and initialized.


<uValue>The initial value to assign to the variable.  This can be any valid expression.  If <uValue> is not specified, the variable is initialized to FALSE. There are exceptions:
In the FoxPro dialect the PUBLIC FOX and FOXPRO are initialized with TRUE.
In the other dialects the PUBLIC CLIPPER is initialized with TRUE.


<ArraySpec>The specification for a dynamic array to create.  <ArraySpec> is one of the following:
<idArray>[<nElements>, <nElements>, <nElements>]
All dimensions except the first are optional.
<idArray> is a valid identifier name for the array to create.  Array elements are initialized to NIL.
<nElements> defines the number of elements in a particular dimension of an array.  The number of dimensions is determined by how many <nElements> arguments you specify.
<Type> & <ClassLibrary>The compiler recognizes the AS <Type> and the AS <Type> of <Classlibrary> clauses in the FoxPro dialect.
The <Type>  and <ClassLibrary> clauses are ignored because dynamic memory variables are always of type USUAL
<arrayName>Variable name of array . The array will have the dimensions as declared with <nRows> and <nColumns>. The array may be declared with parentheses as delimiters but also with square brackets.
<nColumns> is optional
We recommend the use of square brackets.


PUBLIC is an executable statement which means you must specify it after any variable declaration statements (i.e., FIELD, LOCAL, and MEMVAR) in the routine that you are defining.


Warning! Any reference to a variable created with this statement will produce a compiler error unless the Undeclared Variables compiler option is checked.


Any declared variables, such as LOCALs, with the same names as existing public or private variables temporarily hide the public or private variables until the overriding variables are released or are no longer visible.


An attempt to create a public variable with the same name as an existing and visible private variable is simply ignored; however the assignment portion of the PUBLIC statement is not ignored.  For example, the following lines of code change the value of the variable x but do not change its scope from private to public:


PRIVATE x := 1000
PUBLIC x := "New value for x"
? x                                        // Result:  "New value for x"


The explanation for this behavior is that, internally, the PUBLIC statement and the assignment are treated as separate statements.  Thus, this code would be treated as follows:


PRIVATE x := 1000
x := "New value for x"
? x                                        // Result:  "New value for x"


The PUBLIC statement is ignored, but the assignment statement is executed, changing the value of the private variable x.


This behavior has an interesting repercussion when you declare a public array using a variable name that already exists as private.  For example:


PRIVATE x := 1000
PUBLIC x[10]
? x[1]                                // Result:  NIL


In this case, the PUBLIC statement is also treated as two separate statements:


PRIVATE x := 1000
x := ArrayNew(10)
? x[1]                                // Result:  NIL

Again, the PUBLIC statement is ignored, and the assignment changes x from a private numeric variable to a private reference to a ten element array.


Attempting to specify a public variable that conflicts with a visible declared variable (for example, LOCAL, GLOBAL, or DEFINE) of the same name is not recognized by the compiler as an error because PUBLIC is not a compiler declaration statement.  Instead, the declared variable will hide the public variable at runtime.  This means that you will not be able to access the public variable at all until the declared variable is released.


In class methods, instance variables (with the exception of access/assign variables) are always more visible than public variables of the same name.  Use the _MEMVAR-> alias to access a public variable within a method if there is a name conflict.  For access/assign variables, use the SELF:  prefix to override a name conflict with a public variable.

Public variables are dynamically scoped.  They exist for the duration of the application or until explicitly released with CLEAR ALL or CLEAR MEMORY.  


PUBLIC Clipper: To include XSharp extensions in an application and still allow the application to run under dBASE III PLUS, the special public variable, Clipper, is initialized to TRUE when created with PUBLIC.


This example creates two PUBLIC arrays and one PUBLIC variable:


PUBLIC aArray1[10, 10], var2
PUBLIC aArray2[20][10]


The following PUBLIC statements create variables and initialize them with values:


PUBLIC cString := Space(10), cColor := SetColor()
PUBLIC aArray := {1, 2, 3}, ;
 aArray2 := ArrayNew(12, 24)

See Also